Tenho dificuldade em entender quando e por que o valor mantido por um Scalar
contê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 @b
como 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 $i
em conjunto @c
se 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 $i
em @b
no exemplo 1 atualizado após o impulso, enquanto $i
em @c
no exemplo 2 não é?
edit : Após o comentário de @ timotimo, incluí a saída de .WHERE
nos exemplos. Isso mostra a identidade escalar (WHICH / logic) de $i
permanece 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).
.WHERE
vez de,.WHICH
poderá 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.