perlの$_[0](デフォルト引数)とか@_(引数リスト)について気になったので調べた

とあるperlのコードを読んでみると、下記のような書き方をしていて気になったので、調べてみました。

sub on { push @{$_[0]{events}{$_[1]}}, $_[2] and return $_[2] }

@_(引数リスト)とは?

@_(引数リスト)とは、サブルーチン(関数)やforforeachなどの制御構文を扱う時に、引数の受け皿となる配列です。

普通、引数と言えば下記のRubyコードのようにプログラマ自身が用意してあげて、関数の呼び出し時に引数に値が代入されるのが一般的です。

# Ruby
def hello(name, age) {
puts 'hello' + name + age // hello tarou 19
end
hello('tarou', 19)

しかし、perlでは@_(引数リスト)が用意されており、その引数リストに代入すると言う形を取っています。

perlにはData::Printerと言う変数のデータ構造を見るのに便利なモジュール(他言語で言うライブラリ)があるので、早速@_の中身を見てみましょう。

use Data::Printer;
sub hello {
p @_;
};
hello('tarou', 19);
= result
[
[0] "tarou",
[1] 19
]

確かに@_引数リストに引数が代入されているのが分かりますね。

$[0]とか$[1]とかの使い方

上記の説明で@_に引数が入ることが分かりましたが、引数リストの要素を1つずつ取り出したい時が絶対にあるはずです。そう言う時には、$_[0]を使うと良いです。

実際に以下のコードで試してみます。

use Data::Printer;
sub hello {
p $_[0];
p $_[1];
p $_[2];
p @_;
}
hello( 'tarou', 19 );
= result
"tarou"
19
undef
[
[0] "tarou",
[1] 19,
[2] undef
]

上記では引数を2つしか与えていないので$_[2] = undefになるのは分かるのですが、$_[2]と1回定義した影響で@_(引数リスト)に3番目の引数が作られているのが興味深いっすね。

クラスやインスタンス(オブジェクト)での@_の動き

実際のところ上記の例のように関数だけを使うよりも、関数はクラスの中でメソッドとして使うことの方が多いでしょう。

package Sample {
use Data::Printer;
use Moo;
sub hello {
p @_;
}
};
my $self = Sample->new;
$self->hello( 2, 43 );
= result
[
[0] Sample  {
Parents       Moo::Object
public methods (1) : hello
private methods (0)
        internals: {}
},
[1] 2,
[2] 43
]

ReratedPosts

perlモジュール「Exporter」の使い方
Mojoliciousで静的ファイル(html)を読み込ませるための設定法
Mojoliciousでの設定ファイル(Configプラグイン)の使い方とか一例を解説する
Perlモジュール「Moo」(Moose)の使い方をまとめてみる
Mojoliciousを使う時のMojo::Base -baseとかの使い分けのまとめ
perlのgrep関数の使い方|変数とか戻り値とか複数条件とかのまとめ