Thank you for the report. This is now fixed.

Fix: https://github.com/rakudo/rakudo/commit/97359ae42e
Test: https://github.com/perl6/roast/commit/1ed4d128d2

It's worth noting the fix is somewhat tangental to the original issue and the 
issue isn't actually a bug.

What happens in the original issue is you keep returning the same container for 
each item mapped over (in the case of S///, it was the $/ variable). And 
depending on how you fetch the results, you get the *latest* value of that 
container. The most curious example of this effect is:

    [12:40] <AlexDaniel> m: say <a1 a2 a3>.map({S/huh//})
    [12:40] <+camelia> rakudo-moar 9a3c35: OUTPUT«(a1 a2 a3)␤»
    [12:40] <AlexDaniel> m: say eager <a1 a2 a3>.map({S/huh//})
    [12:40] <+camelia> rakudo-moar 9a3c35: OUTPUT«(a3 a3 a3)␤»

The first version is lazy, and the value inside $/ container is "used" 
somewhere in say before it gets updated to the next value. In the second 
version, the `eager` statement modifier gets rid of that lazines, so the `say` 
gets three items, all of them the $/ container, and so it naturally contains 
whatever the last value
that was stored in it (in this case "a3"), which is why we get three items that 
are the same.

The rest of the weirdness in this ticket is all due to the same reason, except 
it may appear to not be present due to laziness, or not appear on first 
iteration but then appear on second one, due to first version evaluated for 
each lazily generated value, but then those get stored in the list's $!reified 
attribute and keep getting updated to new values as the list is reified 
further. The result is only the second iteration notices those updates.

Lastly, why is this ticket fixed now? We determined that S/// is actually not 
supposed to return $/. So for an unrelated reason it no longer returns the same 
container on multiple iterations, fixing this bug by a happy accident \o/

Cheers,
ZZ

Reply via email to