In article <slrnguefcc.fpg.nospam->,
Ilya Zakharevich <nospam-> wrote:
>I managed to confuse myself in a teaspoon... Consider
>
> perl -wle "my $x; BEGIN{ $x=12 } print $x"
> 12
>
>I would expect it to warn that $x is uninitialized, and print
>nothing. The reasoning goes like that:
>
> AT COMPILE TIME:
> `my' is seen; after this $x is considered as lexical
> BEGIN is compiled and executed; $x becomes 12
> `print' is compiled
>
> AT RUN TIME
> `my' is executed.[*] Variable $x becomes undef
> `print' is executed
>
>Apparently,[*]-action is not executed in this context. The question
>is: why? Is it documented?
In "man perlsub", under "Private Variables via my()", I see both
The parameter list to my() may be assigned to if desired, which
allows you to initialize your variables. (If no initializer is
given for a particular variable, it is created with the
undefined value.)
and
A "my" has both a compile-time and a run-time effect. At
compile time, the compiler takes notice of it. The principal
usefulness of this is to quiet "use strict 'vars'", but it is
also essential for generation of closures as detailed in
perlref. Actual initialization is delayed until run time,
though, so it gets executed at the appropriate time, such as
each time through a loop, for example.
I think "Actual initialization" refers to explicit assignment via "=",
so if there's no initialization, there's no run-time assignment.
So I think
(If no initializer is given for a particular variable, it is
created with the undefined value.)
is inaccurate: it's always created undef.
So I'm thinking the the sequence is:
- compile time:
= variable is created
= since it has to have SOME value in Perl, it's set to undef
- run time:
= if an explicit initializer is provided, the assignment is done
= so if no explicit initializer is provided, it is unchanged
That is, that
my $y = 123;
is equivalent to
my $y; BEGIN { undef $y; }
$y = 123; # assigned at run time
$y;
and
my $z;
is
my $z; BEGIN { undef $z; }
$z;
That seems consistent with the examples and with
perl -wle 'my $x = 13; BEGIN{ print "in begin ", $x; $x=12 } print $x'
Use of uninitialized value $x in print at -e line 1.
in begin
^ both showing that it's created undef
13
--
Tim McDaniel,