プッシュされたScalar
コンテナーによって保持されている値がプッシュ後に影響を受ける時期と理由を理解するのが困難です。2つの様式化された例で、より複雑な状況で遭遇した問題を説明しようと思います。
*例1 *最初の例では、スカラー$i
がの@b
一部として配列にプッシュされList
ます。プッシュ後、スカラーが保持する値は、$i++
命令を使用したforループの後の反復で明示的に更新されます。これらの更新は、配列の値に影響を及ぼします。for @b
ループの最後で、@b[0;0]
はに等しく3
、もはやにはなりません2
。
my @b;
my $i=0;
for 1..3 -> $x {
$i++;
say 'Loose var $i: ', $i.VAR.WHICH, " ", $i.VAR.WHERE;
if $x == 2 {
@b.push(($i,1));
say 'Pushed $i : ', @b[0;0].VAR.WHICH, " ", @b[0;0].VAR.WHERE;
}
}
say "Post for-loop";
say "Array : ", @b;
say 'Pushed $i : ', @b[0;0].VAR.WHICH, " ", @b[0;0].VAR.WHERE;
出力例1:
Loose var $i: Scalar|94884317665520 139900170768608
Loose var $i: Scalar|94884317665520 139900170768648
Pushed $i : Scalar|94884317665520 139900170768648
Loose var $i: Scalar|94884317665520 139900170768688
Post for-loop
Array : [(3 1)]
Pushed $i : Scalar|94884317665520 139900170768688
*例2 * 2番目の例では、スカラー$i
はループ変数です。にもかかわらず$i
、それは(今暗黙的にではなく、明示的ではない)押された後に更新され、値の$i
配列では@c
ないではない
プッシュ後に変更。つまり、forループの後に、それはまだです2
、ではありません3
。
my @c;
for 1..3 -> $i {
say 'Loose var $i: ', $i.VAR.WHICH, " ", $i.VAR.WHERE;
if $i == 2 {
@c.push(($i,1));
say 'Pushed $i : ', @c[0;0].VAR.WHICH, " ", @c[0;0].VAR.WHERE;
}
}
say "Post for-loop";
say "Array : ", @c;
say 'Pushed $i : ', @c[0;0].VAR.WHICH, " ", @c[0;0].VAR.WHERE;;
出力例2:
Loose var $i: Scalar|94289037186864 139683885277408
Loose var $i: Scalar|94289037186864 139683885277448
Pushed $i : Scalar|94289037186864 139683885277448
Loose var $i: Scalar|94289037186864 139683885277488
Post for-loop
Array : [(2 1)]
Pushed $i : Scalar|94289037186864 139683885277448
質問:なぜ$i
に@b
いる間、プッシュ後に更新例1の$i
中@c
の例2ではないでしょうか?
編集:@timotimoのコメントに続いて、出力を.WHERE
例に含めました。これは、(WHICH /論理)スカラーIDが$i
変化しない一方で、メモリアドレスがさまざまなループの反復によって変化することを示しています。しかし、例2でプッシュされたスカラーが古いアドレス( "448")と組み合わせて同じWHICH-identityに関連付けられたままになる理由は説明されていません。
.WHERE
代わりにを使用する.WHICH
と、スカラーがループのたびに実際には異なるオブジェクトであることがわかります。これは、先のとがったブロックが「呼び出され」、署名が各呼び出しで「バインド」されるために発生します。