shiftを省略した時の対象は@_だけじゃないのね
へぇー的なネタ。
よく
my $self = shift;
というコードがありますが、これは
my $self = shift @_;
の省略形な訳であります。
で、引数省略時は常に@_が対象となるのかと思いきやそうでは無かったという話。
1.pl
↓のコードをご覧下さい。()
use strict; use warnings; use Perl6::Say; use Data::Dumper; @_ = ('YYY'); my $x = shift; say $x; say q/### \@ARGV/; say Dumper \@ARGV; say q/### \@_/; say Dumper \@_;
これを↓のようにXXXと引数あげて実行します。
perl 1.pl XXX
YYYが出ると思いきや結果はなんと↓
$ perl 1.pl XXX XXX ### \@ARGV $VAR1 = []; ### \@_ $VAR1 = [ 'YYY' ];
shift省略時に@_じゃなくて@ARGVを見にいってました。
で、@_じゃなくて@ARGVを見る境界線はどこなのかと思って見てみました。
2.pl
スコープをたしてみるる。
use strict; use warnings; use Perl6::Say; { my $x = shift; say $x; }
$ perl 2.pl XXX XXX
ここではまだ@ARGVを見てました。
3.pl
普通の使い方。こりゃさすがに@_でしょ(違ってたら汗出るわ)
use strict; use warnings; use Perl6::Say; sub foo { my $x = shift; say $x; } foo('YYY');
$ perl 3.pl YYY
良かった良かった。
4.pl
コードリファレンスの場合。
use strict; use warnings; use Perl6::Say; my $sub = sub { my $x = shift; say $x; }; $sub->("YYY");
$ perl 4.pl XXX YYY
そうだよね。そうだよね。
5.pl
mainパッケージ以外でもそうなのかという点でこれがちょっと以外だった。
use strict; use warnings; package Foo; use Perl6::Say; use Data::Dumper; @_ = ('YYY'); my $x = shift; say $x;
$ perl 5.pl XXX XXX
@ARGVを見てる模様。
結論
パッケージ内のルートのスコープの時だけ@ARGVを見るという仕様かしら。
追記
id:usuihiro1978さんに
「それらくだ本で・・・(ry」
と言われたYO!
参考(っていうかそのもの)
http://perldoc.perl.org/functions/shift.html