Shogo's Blog

Dec 24, 2023 - 1 minute read - perl

5.36以降でのサブルーチンプロトタイプを復習する

この記事は、Perl Advent Calendar 2023 21日目の記事(代打)です。 20日目は@doikojiで「低レベルperlスクリプトのススメ(その2)」でした。


いよいよネタが尽きて途方にくれているいっちーです。 ネタも尽きてn番煎じな気はしますが、サブルーチンプロトタイプの書き方について復習です。

プロトタイプ

サブルーチンプロトタイプとは一言でいうと、引数パーサーの挙動をカスタマイズする仕組みです。 たとえば、Perlの組み込み関数 push は第一引数の配列に要素を追加する関数ですが、 これと同じものを普通は定義できません。

sub my_push {
    # TODO: 中身を実装する
}

my @hoge = (1, 2);
my_push @hoge, 3, 4, 5;
# my_push 1, 2, 3, 4, 5; と配列が展開されてしまって、 `@hoge` にはアクセスできない

Perlのサブルーチンプロトタイプについて」から自作pushの例を引用します。

sub my_push(\@@){
  my ($arr_ref, @arr) = @_;
  for(@arr){
    $$arr_ref[$#$arr_ref+1] = $_;
  }
}
my @hoge = (1, 2);
my_push @hoge, 3, 4, 5;
# my_push \@hoge, 3, 4, 5; と解釈される

Perl 5.36からの変更点

Perl 5.36から v5.36 feature bundle で ‘signatures’-featureが有効化されるようになりました。 待望のサブルーチンへの引数リスト導入です!

use v5.36;

sub foo ($left, $right) {
    return $left + $right;
}

これ自体は歓迎すべきことですが、旧来のプロトタイプ宣言の方法と文法が衝突しています。 そのためプロトタイプには新しい宣言方法が導入されました。 さきほどの my_push は以下のようになります。

use v5.36;

sub my_push :prototype(\@@) ($arr_ref, @arr) {
  for(@arr){
    $$arr_ref[$#$arr_ref+1] = $_;
  }
}

まとめ

力尽きたのでここまで・・・サブルーチンプロトタイプでできることは参考文献を参照してください。

Perl 5.36 から引数リストの書き方が変わりました。 それに合わせてプロトタイプの書き方も変わっています。 新しい方法にも慣れていきましょう!


明日22日目は@shogo82148で「PerlのHTTP::Tinyがv0.083からデフォルトでTLSの証明書を検証するようになった件」です。 お楽しみに!

参考