perlのmy変数の使用範囲について

[上に] [前に] [次に]
さだぼう [E-Mail] 2000/02/15(火) 11:40:36
perl5で,ある条件を満たすときに配列を書きなおして,
条件にあうものに変える処理をするために
概略として次の形になるサブルーチンを書きました。
@aはlocalやmyの宣言をしていない変数です。

sub sub1{
my @n_a = @a;

sub new {@a = @n_a}

loop: for ($i=0; $i<=$#a; $i++) {
push(@n_a, shift(@n_a));
$c=&sub2(@n_a,@a);
if ($c>0) {&new; next loop}
elsif($c<0){next loop}
$d=&sub3(@n_a,@a);
if ($d>0) {&new; next loop}
elsif($d<0){next loop}
}
}

しかし場合によって,@aが@n_aで書きなおされたり
書きなおされなかったりで,動作が怪しくなりました。
結局myをlocalにして解決したのですが,
質問としては,この場合,@n_aはサブルーチンnewの
中から参照されているのでしょうか,いないのでしょうか。

青ラクダ本には,myは「取り囲む一番内側のブロック,サブルーチン,
(中略)の中でのみ存在されることを意味する」とあります。
これを私は,@n_aがnewを含むsub1内で使える,と解釈したのですが,
本当はどうなのでしょうか。よろしくお願いします。

kept 2000/02/15(火) 13:02:07
ちょっとよくわからないのですが・・・sub2,sub3てどんな関数?

>質問としては,この場合,@n_aはサブルーチンnewの
>中から参照されているのでしょうか,いないのでしょうか。
これを検証するために下記のコードを書いてみましたが、
@n_aはnewの中から参照されてるようです。

テストコード(test.pl)
@a = ( 1, 2, 3, 4, 5 );
sub sub1 {
    my @n_a = ( 5, 4, 3, 2, 1 );
    sub new { @a = @n_a;}
    &new();
}

&sub1();
print @a;
exit;

実行結果
perl test.pl
54321

問題があるとすれば別のところではないかと思います。
間違っていたらごめんなさい。

さだひろ [HomePage] 2000/02/15(火) 19:16:25
質問者です。メインルーチンから呼ぶとmyでも動いた
のに,別のサブルーチンから呼ぶと&newは確かに呼び出されて
いたのに,@aは書き換わらなかったのです。
localを使えば済んだ話なのですが,
サブルーチンの中のサブルーチンというものの扱いがイマイチ
分からないのでそこを含めて解説していただけたらうれしいです.

[上に] [前に] [次に]