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