in reply to Re^3: list assignment and undef (actual)
in thread list assignment and undef

Very interesting. Where in the source were you looking?

pp_aassign in pp_hot.c. The ops (as seen in -MO=Concise) are found in pp_*.c. Prefix pp_ to the name seen in -MO=Concise and that's the name of the function that implements them.

It seems that different cases are handled quite differently

I don't know why you say that. The only difference I see is accounted for by the fact that post-increment (and post-decrement) return a copy of the variables original value. (They can't return the variable they are incrementing or decrementing because it no longer has the right value.)

This defies any simple explanation of cached lists generated at compile time

I don't know how you can say that. You haven't tested cached lists at all. You never use the same list twice.

Replies are listed 'Best First'.
Re^5: list assignment and undef
by ig (Vicar) on Aug 26, 2009 at 01:04 UTC
    post-increment (and post-decrement) return a copy of the variables original value.

    Thanks, I hadn't appreciated that but it makes perfect sense and explains the second and third cases.

    You haven't tested cached lists at all. You never use the same list twice.

    In each case I use (1..2). Is it a different list each time?

    In the fifth case I was expecting that $_ is an alias to the elements of the list the foreach is iterating over and that that list would be the elements of the list (1..2) rather than the lvalues of the LHS of the list assignment for the reason you gave previously that the elements of the LHS list are immortal. Furthermore, I expected that the values of $_ would be the same as in the first case where $_ should also be aliased to the elements of the list (1..2). Obviously my understanding / expectation is wrong, but I don't know where. The SV instances displayed by Dump() in the first and fifth cases are different and I don't know why.

      In each case I use (1..2). Is it a different list each time?

      What I called caching is actually constant flattening. That means each op instance is independent.

      You only visit each element of each flattened list once. So if you had changed it, you would never know.

      The bug is that the "constants" of the list into which 1..2 is flattened aren't marked as read-only.

      Except "for constant .. constant" is optimised to not flatten the list. And with this, my question is answerd.

      >perl -le"for (1..2) { print $_++ for 1..2 }" 1 2 1 2 # Disables the "for constant .. constant" optimisation >perl -le"for (1..2) { print $_++ for (),1..2 }" 1 2 2 3 >perl -le"for (1..2) { map print($_++), 1..2 }" 1 2 2 3