in reply to Re^4: Have you netted a Perl Monk or Perl Pretender in 5 minutes or less?
in thread Have you netted a Perl Monk or Perl Pretender in 5 minutes or less?

#!/usr/bin/perl -w use strict; our $c = 2; print "Before: c=$c\n"; my $c = 1 unless $c; print "After: c=$c\n";
This highlights the duality of my.

If you had actually run that, you should have got the compiler error:

"my" variable $c masks earlier declaration in same scope at 492281.pl +line 6.
because you had warnings on.

Let's do it line by line:

our $c = 2;
The global variable also known as $main::$c is formally declared (for strictness), and assigned the value 2.
print "Before: c=$c\n";
The value of $main::$c (2) is printed.
my $c = 1 unless $c;
If the current $c variable is true, declare a lexical variable with the same name, and assign it the value 1. On the first (and here only) pass, $c is just shorthand for the global $main::$c, and it's value is 2, so the lexical assignment doesn't happen.

However, the lexical creation did! Until the lexical $c goes out of scope (in this case, at the end of the file), all instances of $c refer to this lexical variable, and not to the global $main::$c. To access $main::$c, the "long" name must be used, as the short name points to something different.

print "After: c=$c\n";
The value of the lexical $c is printed. However, since the assignment didn't happen, it's still undefined. And if you'd actually tried it, you would have seen this:
Use of uninitialized value in concatenation (.) or string at 492281.pl + line 7.
just before the "After..." string was printed.

To separate these issues, try changing my $c to my $d:

#!/usr/bin/perl -w use strict; our $c = 2; print "Before: c=$c\n"; my $d = 1 unless $c; print "After: d=$d\n";
gives
Before: c=2 Use of uninitialized value in concatenation (.) or string at 492281.pl + line 7. After: d=
Do you see why?

-QM
--
Quantum Mechanics: The dreams stuff is made of

Replies are listed 'Best First'.
Re^6: Have you netted a Perl Monk or Perl Pretender in 5 minutes or less?
by Anonymous Monk on Sep 15, 2005 at 21:52 UTC
    So are we admitting that this is a poor interview question? And bad design on the part of Perl in regards to statement modifiers? Compare...
    #!/usr/bin/perl -w use strict; our $c = 2; print "Before: c=$c\n"; unless($c){my $c = 1} print "After: c=$c\n";
      So are we admitting that this is a poor interview question?
      This behavior of my is a fact. Precisely because of this fact, it's a good interview question. Knowing where the cracks in the armor lie is just as important as wearing the armor in the first place.

      -QM
      --
      Quantum Mechanics: The dreams stuff is made of

        Combining my with if/unless often leads to buggy behavior and is definitely not a "best practice". Things like the strange behavior of my $x if 0 (which is often used for "tricks") have been deprecated since 5.9.1 and will be removed eventually.