例えば、こんなのを書いてみる。
use Readonly; my @values = (1, 2, 3); Readonly::Array my @arr => @values;
これを-MO=Deparseしてみると、こんな結果になる。
$ perl -MO=Deparse test.pl use ReadOnly; my(@values) = (1, 2, 3); &Readonly::Array(\my(@arr), @values); test.pl syntax OK
これを、実行してみると、怒られてしまう。
% perl -MO=Deparse test.pl | perl test.pl syntax OK Can't use string ("1") as an ARRAY ref while "strict refs" in use at /opt/local/lib/perl5/site_perl/5.8.8/Readonly.pm line 290.
よく分からないのでデバッグしてみた。
$ perl -d test.pl Loading DB routines from perl5db.pl version 1.28 Enter h or `h h' for help, or `man perldebug' for more help. main::(test.pl:2): my @values = (1, 2, 3); DB<1> s main::(test.pl:3): Readonly::Array my @arr => @values; DB<1> Readonly::Array(/opt/local/lib/perl5/site_perl/5.8.8/Readonly.pm:290): 290: my $badtype = _is_badtype (ref tied @{$_[0]}); DB<1> x @_ 0 ARRAY(0x800c48) empty array 1 1 2 2 3 3 DB<2> q $ perl -MO=Deparse test.pl | perl -d Loading DB routines from perl5db.pl version 1.28 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. test.pl syntax OK main::(-:2): my(@values) = (1, 2, 3); DB<1> s main::(-:3): &Readonly::Array(\my(@arr), @values); DB<1> Readonly::Array(/opt/local/lib/perl5/site_perl/5.8.8/Readonly.pm:290): 290: my $badtype = _is_badtype (ref tied @{$_[0]}); DB<1> x @_ 0 1 1 2 2 3 DB<2> q
そのまま実行した場合はReadonly::Arrayに第1引数として配列の参照が渡っているのに、Deparseされたものはそれが渡されなくなっている。
"\my(@arr)"というのがいけないのか?
試してみる。
$ perl -le 'print \my(@arr)' $ perl -le 'print \my @arr' ARRAY(0x800b34)
"\my @arr"と、括弧でくくらなければ、ちゃんと配列の参照になるらしい。括弧でくくってしまうと、そうはならない。
ということは"-MO=Deparse"のdeparse結果が間違っていない、ということか。
use ReadOnly; my(@values) = (1, 2, 3); &Readonly::Array(\my @arr, @values);
こう出力されるのが正しい、っぽい。
"\my(@arr)"と書いてしまうと、何が起こるのだろう?
$ perl -le 'print \() == \my(@arr)' 1 $ perl -le 'print \()'
"\()"って何だ?
追記
要するに'\my @arr'を-MO=Deparseすると良くないらしい。
print \my @arr, "\n";
$ perl test.pl ARRAY(0x800b10) $ perl -MO=Deparse test.pl | perl test.pl syntax OK