in reply to How foreach loops decide what to iterate through

In principle, foreach iterates over a list that is constructed before the looping begins, so you should have no concerns about making extra work for each iteration by having a complex expression for the list being iterated over.

In practice, iterations over a range (foreach ($x .. $y)) or an array (even one built on the fly: foreach (@{[ sort @x ]})) are optimized to not need to load the full list ahead of time. Since this optimization shouldn't introduce differences in behaviour, what you are seeing with a push in the loop is a bug.