I have difficulty understanding when and why the value held by a pushed Scalar container is affected after the push. I'll try to illustrate the issue that I ran into in a more complicated context in two stylized examples.
*Example 1 * In the first example, a scalar $i is pushed onto an array @b as part of a List. After the push, the value held by the scalar is explicitly updated in later iterations of the for loop using the $i++ instruction. These updates have an effect on the value in the array @b: at the end of the for loop, @b[0;0] is equal to 3, and no longer to 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;
Output example 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
* Example 2 * In the second example, the scalar $i is the loop variable. Even though $i is updated after it has been pushed (now implicitly rather than explicitly), the value of $i in array @c does not
change after the push; i.e. after the for loop, it is still 2, not 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;;
Output example 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
Question: Why is $i in @b in example 1 updated after the push, while $i in @c in example 2 is not?
edit:
Following @timotimo's comment, I included the output of .WHERE in the examples. This shows the (WHICH/logical) scalar-identity of $i stays the same, while its memory address changes through the various loop iterations. But it does not explain why in example 2 the pushed scalar remains tied to the same WHICH-identity in combination with an old address ("448).