Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re^3: Have you netted a Perl Monk or Perl Pretender in 5 minutes or less?

by jbrugger (Parson)
on Sep 15, 2005 at 04:16 UTC ( [id://492116]=note: print w/replies, xml ) Need Help??


in reply to Re^2: 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?

That prints out:
Global symbol "$c" requires explicit package name at programname.pl li +ne 5. Global symbol "$c" requires explicit package name at programname.pl li +ne 6. Global symbol "$c" requires explicit package name at programname.pl li +ne 7. Execution of programname.pl aborted due to compilation errors.
Oh... you didn't use strict :)

"We all agree on the necessity of compromise. We just can't agree on when it's necessary to compromise." - Larry Wall.

Replies are listed 'Best First'.
Re^4: Have you netted a Perl Monk or Perl Pretender in 5 minutes or less?
by Anonymous Monk on Sep 15, 2005 at 15:27 UTC
    Um. This is really a serious question. Is there something useful that example accomplishes, or is it just trying to point out a Perl anonomly (some might call it broken behavior)?
    #!/usr/bin/perl -w use strict; our $c = 2; print "Before: c=$c\n"; my $c = 1 unless $c; print "After: c=$c\n";
      #!/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

        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";
      It tests the candidate's understanding of Perl syntax. To understand that line you must know the effects of using unless (and if I'm asking the questions that will quickly turn into what Perl considers true and false values) as well as execution order in a statement. Put concicely, it says that if $c exists and is true maintain it's value, otherwise set it to 1. It is an occasionally useful construct for fixing user input errors and the like.

      I did notice that the way you've got it written it is a trick question - if you set the original value of $c to be 0 or "" the "my" would produce a warning about re-declaring a variable that was declared in the same scope.
        To understand that line you must know the effects of using unless (and if I'm asking the questions that will quickly turn into what Perl considers true and false values) as well as execution order in a statement. Put concicely, it says that if $c exists and is true maintain it's value, otherwise set it to 1.
        Wrong. It is an anomoly caused by the interaction between lexical scopes created by "my" and postfix conditionals. To put it correctly, if $c is false, then set it to one. If $c is true then set it to undef. If you actually try running that snippet you'll learn what it really does.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://492116]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (5)
As of 2024-04-25 10:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found