foreachの制御変数にmy変数が使えないとは?

[上に] [前に] [次に]
kala 1999/12/01(水) 16:04:40
「プログラミングPerl」を読んでいて、myとforeachの関係について分からない点が出ました。

「myで作成した構文スコープを持つ変数を参照する場合には、これらの変数にアクセスできるように、myと同じブロックスコープの中でフォーマットやサブルーチンを宣言しなければならない。(脚注:クロージャと構文スコープとforeachのエイリアス機構に由来する難解な理由のため、このようなmy変数をforeachループの制御変数にしてはならない。なぜなら、名前の付いたサブルーチンやフォーマットは、最初のバインディングだけとコンパイルされるからである。)」(「プログラミングPerl」、120ページ)

何回か読み返しましたが今いち意味が分かりません。

sub test {
    my(@a,$b);
    foreach $b (@a) { ... }
}

こういうのがいけない、ということなのでしょうか。でもよく使っていますし、これまでのところ正常に動いています。

少し解説していただければ嬉しいです。

mm 1999/12/06(月) 02:08:30
本題の方は、よく分からないんですが、
まず、my $b が foreach のループ変数の局所化するためのものなら、
これは不要です。↓を参照して下さい。
../199911/99110412.htm

また、上のリンクではウソを書いてしまいました。
foreach のループ変数が my 変数を隠す場合は、ダイナミックには参照できません。
そういうことも含めて、下の例のように、$a が何を指しているのか、
いろいろややこしいことになるおそれがある
ってことではないでしょうか?(よくは分かりませんが)

@b = ('loop');
$a = 'global';
foreach $a (@b) {
p('1:');
}
$test = &test1;
&test2;
&$test;
sub test1 {
my $a = 'lexical';
foreach $a (@b) {
print "2:$a\n";
p('3:');
sub test2 {
print "4:$a\n";
p('5:');
}
return sub {
print "6:$a\n";
p('7:');
}
}
}
sub p { print "$_[0]$a\n"; }


----------- 実行結果 -----------
Variable "$a" will not stay shared at test.cgi line 15.
1:loop
2:loop
3:global
4:lexical
5:global
6:loop
7:global

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