[Melbourne-pm] Pls explain?
mathew.robertson at netratings.com.au
Tue Oct 23 20:21:26 PDT 2007
>>>> my $job_name = "backfill_" if $backfill;
>>> This line above is like writing:
>>> my $a if $b;
>>> So the lexical variable $a only springs into existence if $b is true. Therefore
>>> (since $backfill isn't true)
>> why is it the same?
>> The "my $job_name" should be an isolated statement due to the "="
>> operator, ie: an lvalue is being created.
>> Thus "my $a if $b" doesn't have a lvalue until the "if" is true.
> It's not that complicated. ( did my research)
> When Perl sees this code, it creates a pad slot for $job_name at compile time.
> However, the op which should create a new entry in that pad for that value
> during runtime will only run if the conditional is true. This is true
> regardless of whether we're creating and assigning; or just creating a variable.
> You can find lots more on this bug by searching for:
> my if 0
[ couldn't find much searching for 'perl "my if 0"' - 'perl "my $x if
0"' however is much more helpful - thanks for the pointer ]
I'd see "if 0" as a constant expression -> so the complicated stuff
appears to be that work is being done unnecessarily at runtime.
> Abigail from Perl Monks explains it thus:
> my $x if undef;
> my has compile-time *and* run-time effects. At compile time, the compiler knows
> about the variable, etc. At run-time, values are set, my $x; makes that $x
> becomes undef. So far, so good.
> However, for efficiency reasons, if Perl exits a block, it will actually *not*
> delete any variables lexical to the block. You cannot refer to them anymore (the
> compiler takes care of that), but the data structure build for it remains. Perl
> does this because it is likely that you reenter a block and if the structure
> remains, Perl can save time rebuilding it. However, with my $x if undef, no
> run-time effect on $x happens when reentering the block. (The first time the
> block is entered, the datastructure gets build when $x is used). And since the
> structure doesn't get rebuild, the value doesn't get reset either. So, you have
> created a static variable....
"my $x if undef" should *only* have compile-time effects as the "if
undef" is a constant (albeit false) expression and so should be detected
early in the compile phase (cf. with C's interpretation of "if (0) ...")
**. So the data structure should be built at compile time so that it
doesn't have a runtime hit.
** Note that I'm _not_ assuming that an optimiser is at play here -> it
should be the compiler itself - although the actual optimisation could
be implemented in either, say depending on debugging requirements.
One could argue that the "if 0" should be evaluated at runtime, but that
doesn't gel with the fact that it is a constant expression. Under Perl
constant expressions are candidates for being optimised away by an
optimiser later. The optimisation for the constant expression of "if 0"
would be to always set $x to undef.
An thus re-iterating the requirement that the effect of the "my $x"
should always be to scope $x to undef when the code block is entered.
> It was covered in the "This Week on p5p 2000/05/21"
> Apparently Perl 5.10 throws a big fat warning if it sees this kind of behaviour.
The article itself describes the implementation - not the expected
behaviour based on the rules of the language -> thus ignoring whether
the actual implementation is right (aka static variables) or wrong (a
Interestingly B::Deparse documents that it doesn't correctly handle "my
$x if 0". Having looked at its output (it has "'???';" for that line),
Deparse looks to be doing the right thing, ie: treating it as a constant
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Melbourne-pm