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).