Subscribed unsubscribe Subscribe Subscribe

'\my @arr'を-MO=Deparseすると

例えば、こんなのを書いてみる。

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