nimdokk has asked for the wisdom of the Perl Monks concerning the following question:

I thought I had gotten a pretty good grasp of scoping and variables both from the various tutorials here, several classes on Perl and also the Camel Book. I was testing out a section of code that will manipulate a variable within a code block and I was thinking that I would not have to reassign it back to the original value when I was finished since I assign it once at the start of the main package. I proceeded to test this out with the following code snippet.

#! /usr/local/bin/perl -w use strict; my $hero="Batman"; my $car="Pinto"; my $year=sprintf("%04d", (localtime)[5]+1900); BLOCK0:{ print "In the first block, \$hero is $hero and \$car is $car. +\n"; } BLOCK1:{ my $hero="Superman";my $car="Porsche";print "In next code blo +ck \$hero is $hero and \$car is $car.\n"; } BLOCK2:{ print "In next code block, \$hero is $hero and \$car is $car +.\n"; } BLOCK3:{ print "To start, \$year is $year\n";} BLOCK4:{ my $year=--$year; print "We change \$year to $year\n"; } BLOCK5:{ print "And now, \$year is $year\n"; } __DATA__ In the first block, $hero is Batman and $car is Pinto. In next code block $hero is Superman and $car is Porsche. In next code block, $hero is Batman and $car is Pinto. To start, $year is 2003 We change $year to 2002 And now, $year is 2002

According to everything I've seen, the last line should be: And now, $year is <b>2003</b>. Obviously, this is not the case and I am trying to figure out why this is so. I have also tried hardcoding a value into $year at the start and still get the same result. I am suspecting the decrement operator(?) is doing something to the value of $year in the main package, but what and how.


"Ex libris un peut de tout"

Replies are listed 'Best First'.
Re: Scoping Problem
by VSarkiss (Monsignor) on Jun 25, 2003 at 18:55 UTC

    In my $year = --$year;the decrement operator is changing the $year in the OUTSIDE scope, then assigning it to the lexical $year in the INSIDE scope (which is the one that your print statement in BLOCK4 sees). Remember, until that statement finishes successfully, the INNER $year doesn't exist.

    You could get the behavior you're looking for with: my $year = $year - 1;which doesn't change the value of the OUTER $year.

    Update
    Added example in second para.

      Thanks, I actually tried it with

      my $year=$year-1;

      and not seen any problems. I think I'll just have to stick with that.


      "Ex libris un peut de tout"
Re: Scoping Problem
by tcf22 (Priest) on Jun 25, 2003 at 19:04 UTC
    --$year actually decrements the variable $year outside the block, because the right side is evaluated first, before the local copy is created. It doesn't simply return the value 1 less than year and assign it to the local variable year.
Re: Scoping Problem
by antirice (Priest) on Jun 25, 2003 at 20:42 UTC
    BLOCK4:{ my $year=$year;--$year; print "We change \$year to $year\n"; +}

    As mentioned before, $year's scope doesn't change until after my $year = $year; has executed. Thus, if you change $year anywhere after that statement executes, it will just change the $year within the scope and leave global $year alone.

    antirice    
    The first rule of Perl club is - use Perl
    The
    ith rule of Perl club is - follow rule i - 1 for i > 1