[Melbourne-pm] Pls explain?

Jacinta Richardson jarich at perltraining.com.au
Tue Oct 23 18:33:33 PDT 2007

Mathew Robertson wrote:

>>>     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

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....

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.

> In any case $job_name would be undef on the first iteration, whether it
> was global or local scoped.  I'd be interested to know why a warning
> isn't produced?

	jarich at tabius:~$ perl -we '$x .= "foo"; print "$x\n"'
	jarich at tabius:~$ perl -we 'use strict; my $x .= "foo"; print "$x\n"'
	jarich at tabius:~$ perl -we 'use strict; my $x; $x .= "foo"; print "$x\n"'

I guess the lack of warnings isn't that unusual.


   ("`-''-/").___..--''"`-._          |  Jacinta Richardson         |
    `6_ 6  )   `-.  (     ).`-.__.`)  |  Perl Training Australia    |
    (_Y_.)'  ._   )  `._ `. ``-..-'   |      +61 3 9354 6001        |
  _..`--'_..-_/  /--'_.' ,'           | contact at perltraining.com.au |
 (il),-''  (li),'  ((!.-'             |   www.perltraining.com.au   |

More information about the Melbourne-pm mailing list