in reply to Scope surprise

Did you know you could actually get the result you expected, just by replacing my with local? It changes the two lexicals into one global variable that temporarily changes value.
local $foo = 1; foo(); local $foo = 2; sub foo { print "foo: $foo\n"; }
Of course, I did have to drop the "use strict;" to make it work, because local is not a variable declaration. You can still prepend "our $foo;" to add the actual declaration, and strict will no longer complain.

Replies are listed 'Best First'.
Re^2: Scope surprise
by ikegami (Patriarch) on Apr 11, 2009 at 18:58 UTC
    Did you just recommend
    our $foo; local $foo = 1; foo(); local $foo = 2; foo(); sub foo { print "foo: $foo\n"; }
    over
    my $foo; $foo = 1; foo(); $foo = 2; foo(); sub foo { print "foo: $foo\n"; }
    Either way, sounds like an awfully complicated way of avoiding passing a parameter.
    foo(1); foo(2); sub foo { my ($foo) = @_; print "foo: $foo\n"; }
      Did you just recommend ... over ...
      Yes I did. Not for this particular example, but examples (made up in just a few minutes) are always simpler than real life situations. Anyway, the basic idea here was that the OP could get exactly the result he was hoping for with almost the exact code he originally used, and understands so well. That is remarkable enough to warrant pointing it out.

      A more complex, and likely more true to life example could be this:

      $foo = bar(@params); # You don't know what value $foo has { local $foo = 1; foo(); } sub foo { print "foo: $foo\n"; } # now $foo is restored!
      You don't know what value $foo had, and if you want to restore the value it originally had, local comes in very handy.

      You may not even know if it matters whether $foo is restored, and you don't even have to know. You can just use local anyway, just to be on the safe side. That kind of localization of side effects is a very good tool to have in the toolbelt.

      Either way, sounds like an awfully complicated way of avoiding passing a parameter.
      Not a parameter. A setting. For example, suppose you temporarily want to change the settings for a module like Data::Dumper, and not disturb its value for everywhere else besides this piece of code:
      { local $Data::Dumper::Terse = 1; $baz = Dumper($data); }

        Anyway, the basic idea here was that the OP could get exactly the result he was hoping for with almost the exact code he originally used, and understands so well.

        and that change would be to use
        my $foo = 1; foo(); -my $foo = 2; +$foo = 2;

        Not adding our and changing my to local.

        Not a parameter. A setting. For example, suppose you temporarily want to change the settings for a module like Data::Dumper

        Since it worked with lexicals, I somehow doubt we're talking about config variables in another modules. Either he needs a global var (where there should only be one decleration) or a parameter (likely because it's a common beginner mistake to avoid parameters). The likeliness of it being a parameter is reinforced by the set-and-call pattern.