Tenho dificuldade em entender quando e por que o valor mantido por um Scalarcontêiner enviado é afetado após o envio. Tentarei ilustrar a questão que encontrei em um contexto mais complicado em dois exemplos estilizados.
* Exemplo 1 * No primeiro exemplo, um escalar $ié empurrado para uma matriz @bcomo parte de a List. Após o envio, o valor mantido pelo escalar é explicitamente atualizado nas iterações posteriores do loop for usando a $i++instrução Essas atualizações afetam o valor da matriz @b: no final do loop @b[0;0]for , é igual a 3, e não mais 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;
Exemplo de saída 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
* Exemplo 2 * No segundo exemplo, o escalar $ié a variável de loop. Mesmo que $ié atualizado depois de ter sido empurrado (agora implicitamente, em vez de explicitamente), o valor de $iem conjunto @cse não
mudar após o impulso; ou seja, após o loop for 2, ainda é , não 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;;
Exemplo de saída 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
Pergunta: Porque é que $iem @bno exemplo 1 atualizado após o impulso, enquanto $iem @cno exemplo 2 não é?
edit : Após o comentário de @ timotimo, incluí a saída de .WHEREnos exemplos. Isso mostra a identidade escalar (WHICH / logic) de $ipermanece a mesma, enquanto seu endereço de memória é alterado pelas várias iterações de loop. Mas não explica por que, no exemplo 2, o escalar empurrado permanece vinculado à mesma identidade WHICH em combinação com um endereço antigo ("448).
.WHEREvez de,.WHICHpoderá ver que o escalar é realmente um objeto diferente a cada vez no loop. Isso acontece porque os blocos pontiagudos são "chamados" e a assinatura é "vinculada" a cada chamada.