例えば、こんなのを書いてみる。
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