undef をデリファレンス再び

http://unknownplace.org/memo/2006/06/20#e001
普通といわれると普通なのかなあ。僕には予想外の動作 *だった* んだけど。

いろんな呼び出しで試してみた。やたらとスクリプトが長くなってしまったが、たいしたことはやっていない。

#!/usr/local/bin/perl

use strict;
use Data::Dumper;

sub my_subroutine {
}

my $undef_scalar = undef;
printf "%s\n", Dumper($undef_scalar);

print "dereference undef\n";
eval { @{ $undef_scalar } };
print $@ if $@;
printf "%s\n", Dumper($undef_scalar);

print "dereference by print\n";
eval { print @{ $undef_scalar }, "\n" };
print $@ if $@;
printf "%s\n", Dumper($undef_scalar);

print "dereference by my\n";
eval { my(@array) = @{ $undef_scalar }, "\n" };
print $@ if $@;
printf "%s\n", Dumper($undef_scalar);

$undef_scalar = undef;
print "dereference by while\n";
eval { while ( @{ $undef_scalar } ) {} };
print $@ if $@;
printf "%s\n", Dumper($undef_scalar);

$undef_scalar = undef;
print "dereference by for\n";
eval { for ( @{ $undef_scalar } ) {} };
print $@ if $@;
printf "%s\n", Dumper($undef_scalar);

$undef_scalar = undef;
print "dereference by foreach\n";
eval { foreach ( @{ $undef_scalar } ) {} };
print $@ if $@;
printf "%s\n", Dumper($undef_scalar);

$undef_scalar = undef;
print "dereference by pop\n";
eval { pop @{ $undef_scalar } };
print $@ if $@;
printf "%s\n", Dumper($undef_scalar);

$undef_scalar = undef;
print "dereference by splice\n";
eval { splice @{ $undef_scalar } };
print $@ if $@;
printf "%s\n", Dumper($undef_scalar);

$undef_scalar = undef;
print "dereference by shift\n";
eval { shift @{ $undef_scalar } };
print $@ if $@;
printf "%s\n", Dumper($undef_scalar);

$undef_scalar = undef;
print "dereference by unshift\n";
eval { unshift @{ $undef_scalar } };
print $@ if $@;
printf "%s\n", Dumper($undef_scalar);

$undef_scalar = undef;
print "dereference by sort\n";
eval { sort @{ $undef_scalar } };
print $@ if $@;
printf "%s\n", Dumper($undef_scalar);

$undef_scalar = undef;
print "dereference by map\n";
eval { map {1} @{ $undef_scalar } };
print $@ if $@;
printf "%s\n", Dumper($undef_scalar);

$undef_scalar = undef;
print "dereference by split\n";
eval { split //, @{ $undef_scalar } };
print $@ if $@;
printf "%s\n", Dumper($undef_scalar);

$undef_scalar = undef;
print "dereference by join\n";
eval { join '', @{ $undef_scalar } };
print $@ if $@;
printf "%s\n", Dumper($undef_scalar);

$undef_scalar = undef;
print "dereference by my_subroutine\n";
eval { my_subroutine( @{ $undef_scalar } ) };
print $@ if $@;
printf "%s\n", Dumper($undef_scalar);
% ./test.pl
$VAR1 = undef;

dereference undef
Can't use an undefined value as an ARRAY reference at ./test.pl line 13.
$VAR1 = undef;

dereference by print
Can't use an undefined value as an ARRAY reference at ./test.pl line 18.
$VAR1 = undef;

dereference by my
Can't use an undefined value as an ARRAY reference at ./test.pl line 23.
$VAR1 = undef;

dereference by while
Can't use an undefined value as an ARRAY reference at ./test.pl line 29.
$VAR1 = undef;

dereference by for
$VAR1 = [];

dereference by foreach
$VAR1 = [];

dereference by pop
$VAR1 = [];

dereference by splice
$VAR1 = [];

dereference by shift
$VAR1 = [];

dereference by unshift
$VAR1 = [];

dereference by sort
Can't use an undefined value as an ARRAY reference at ./test.pl line 71.
$VAR1 = undef;

dereference by map
$VAR1 = [];

dereference by split
Can't use an undefined value as an ARRAY reference at ./test.pl line 83.
$VAR1 = undef;

dereference by join
Can't use an undefined value as an ARRAY reference at ./test.pl line 89.
$VAR1 = undef;

dereference by my_subroutine
$VAR1 = [];

とまあエラーになるときとそうじゃないときがある。どうも引数の配列を変更されるような呼び出しだと、無名 ARRAY のリファレンスになるみたい。@_ を作る時に何か処理してるのかな?