ig has asked for the wisdom of the Perl Monks concerning the following question:
I have the following test program:
use strict; use warnings; use Devel::Peek; my $y; Dump($y); for my $x (undef, 10) { print "\$x = $x\n"; Dump($x); Dump($_) for ( ($x, $y, undef) = 1..10), $x, $y; }
Which produces the following output:
SV = NULL(0x0) at 0x8ad23d0 REFCNT = 1 FLAGS = (PADMY) Use of uninitialized value $x in concatenation (.) or string at ./test +.pl line 10. $x = SV = NULL(0x0) at 0x8ab54fc REFCNT = 2147483499 FLAGS = (READONLY) SV = IV(0x8ab987c) at 0x8ab9880 REFCNT = 2 FLAGS = (IOK,pIOK) IV = 1 SV = IV(0x8ad23cc) at 0x8ad23d0 REFCNT = 2 FLAGS = (PADMY,IOK,pIOK) IV = 2 SV = IV(0x8adf414) at 0x8adf418 REFCNT = 2 FLAGS = (IOK,pIOK) IV = 3 SV = NULL(0x0) at 0x8ab54fc REFCNT = 2147483500 FLAGS = (READONLY) SV = IV(0x8ad23cc) at 0x8ad23d0 REFCNT = 2 FLAGS = (PADMY,IOK,pIOK) IV = 2 $x = 10 SV = PVIV(0x8ab86ac) at 0x8ad2410 REFCNT = 2 FLAGS = (PADTMP,IOK,POK,READONLY,pIOK,pPOK) IV = 10 PV = 0x8af56a0 "10"\0 CUR = 2 LEN = 4 Modification of a read-only value attempted at ./test.pl line 12.
It appears that both $x and $y are lexical (my) variables, and yet there are significant differences between their values and how they behave.
In the first iteration of the loop, both $x and $y are initially undefined, as is the return from undef in the list which is LHS of the list assignment. The list assignment is in list context and returns the list of lvalues assigned to (Assignment Operators). In the case of $x, the lvalue returned is not $x - a new SV is created and returned, set to the assigned value, and $x is not modified. In the case of $y, the lvalue returned is $y itself, set to the assigned value. In the case of undef, as with $x, a new SV is created and returned, set to the assigned value. Thus $x behaves or is handled like undef rather than like another my variable which also has the value undef.
I am curious about the SVs created for $x and undef. They are neither PADMY nor PADTMP, yet I doubt they are globals. I wonder where they exist (where are the 2 references to them) and what their scopes are. update: I suppose $_ is one of the references, but where is the other?
In the first iteration of the loop, $x is readonly. Assignment to it does not alter it but does not cause a runtime error. Instead, a new SV is created to take the assigned value.
In the second iteration of the loop, $x is again readonly, but this time assignment to it causes a runtime error instead of causing a new SV to be created and assigned to.
I know that in the for loop the loop variable ($x in this case) is aliased to the elements of the list being iterated over. Thus the variable is not an ordinary variable. update: or perhaps I should say that the value is not an ordinary value.
Obviously, undef is handled specially in some cases, but not in all cases (e.g. $y in the first iteration of the loop).
I would appreciate any comments, explanations or pointers to the documentation of source code that might help me understand these behaviors.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: list assignment and undef (deduction)
by ikegami (Patriarch) on Aug 25, 2009 at 17:08 UTC | |
by ikegami (Patriarch) on Aug 25, 2009 at 18:09 UTC | |
by ig (Vicar) on Aug 25, 2009 at 23:38 UTC | |
by ikegami (Patriarch) on Aug 26, 2009 at 00:36 UTC | |
by ig (Vicar) on Aug 26, 2009 at 01:04 UTC | |
| |
|
Re: list assignment and undef (range returns non-temps)
by ikegami (Patriarch) on Aug 25, 2009 at 18:30 UTC | |
by Marshall (Canon) on Aug 26, 2009 at 14:44 UTC | |
by ikegami (Patriarch) on Aug 26, 2009 at 16:54 UTC | |
by Marshall (Canon) on Aug 26, 2009 at 19:58 UTC |