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

In trying to stick with  use strict;use warnings I have had to add a whole bunch of my's and locals. (My dirty secret is I have yet to use local...but I digress)

I'm not one for doing something, "because everyone does it that way."
What started my questioning is the following slice of code
open( HANDLE, "<file"); while( my($line) = <HANDLE> ) { print $line; }
There are probably a few people out there that have no idea why the above segment is wrong (besides error checking, or doing something truly useful in the body of the loop).
I learned to code using C/C++ so it is stuck in my head to use parens everyplace, it just makes things safer...well in C++ at least :)
Here it evaluates $line in a list context, and eats the file so that I only get to process the first line, then exit the loop. Very much not what I wanted.
I have many scripts that I have coded with a line like below at the top (or at the top of a sub..etc..)
my($var); my($othervar) = 43;
Based on my background this looks good to me, but now that I have done some research I don't think it is correct. The correct lines should be:
my $var; my $othervar = 43;
That does assume we don't want to declare multiple items...
my($var1, $var2, $var3);
1. So my questions are, what other nuances are there with my that have either been Gotcha's or could be?
2. Am I wasting memory/speed/other when I declare using parens on a single scalar (building a list only to throw it away?)

While I have you...what is the differences between my and local? my gives "lexical" scope, local gives "dynamic" scope. In the perldoc -f local it says:
"You really probably want to be using `my' instead, because `local' isn't what most people think of as "local"."

Assuming I'm most people, what do I think it means? What does it really do? Why DO you want to use it?
I would assume you want to keep variables in the smallest scope possible, so the memory/stack is given back to the system as soon as it is not needed.

Thanks for the enlightenment!

Replies are listed 'Best First'.
Re: nuances of my, and maybe local
by Chmrr (Vicar) on Sep 27, 2002 at 17:25 UTC

    Read Coping with Scoping by Dominus for the skinny on my vs local. The node I need a simple explantion of the difference between my() and local() is a long discussion on the topic, as well.

    Myself, I seldom use the form of my with parens -- mostly because I create my variables when I need them. If I need a whole bunch of them at once, it's probably because I want the list context, such as at the top of subroutines:

    sub foo { my ($bar, $baz, $troz) = @_; ... }

    perl -pe '"I lo*`+$^X$\"$]!$/"=~m%(.*)%s;$_=$1;y^`+*^e v^#$&V"+@( NO CARRIER'

Re: nuances of my, and maybe local
by Zaxo (Archbishop) on Sep 27, 2002 at 17:34 UTC

    Your excellent examples of my misuse all boil down to context errors. Another gotcha happens when subs are defined to access lexical variables outside their definition. That makes an accidental closure, giving previous calls influence over the state of subsequent ones. That is a source of almighty difficult heisenbugs.

    In effect, local produces a temporary namespace. All code executed within its scope thinks that global variables have the values found in that local namespace. That means you can redefine local $/, *STDERR, $^W, or *CORE::GLOBAL::print, and every sub or builtin called within that scope will honor the new definitions. It is a very handy way to obtain dynamic polymorphism.

    When the local namespace goes out of scope, the previous values are back as if nothing had happened.

    After Compline,
    Zaxo

•Re: nuances of my, and maybe local
by merlyn (Sage) on Sep 27, 2002 at 18:16 UTC
    The easy way to deal with my is to simply erase the two letters of m and y, and use the normal rules for parsing. So
    my ($a) = <STDIN>;
    acts like
    ($a) = <STDIN>;
    and
    my $a = <STDIN>;
    acts like
    $a = <STDIN>;
    Once you get that you just "erase the my" and continue the parse, it's simple to reduce to cases you've already known.

    -- Randal L. Schwartz, Perl hacker

Don't Use Local
by Wally Hartshorn (Hermit) on Sep 27, 2002 at 18:50 UTC

    The short version is you almost never, ever need to use local. Once upon a time, all variables were global. (Bad Perl, bad!) "Okay," they said, "we'll hack in a way to do local variables using the keyword local in Perl 4." That sort of worked, but not very well. So in Perl 5 they came out with my instead. That worked much better. Now they've added our to handle global variables.

    Now, the language gurus (you know who you are) will tell you that what I said isn't really true, but it's close enough to true for most cases. (If you don't understand Einstein, Newton was close enough to get by.)

    Summarizing, use my for the locals, our for the globals, and pretend that local doesn't exist.

    Wally Hartshorn

      I'm pretty sure local existed in Perl 3 as well, and maybe even Perl 2.

      And you still need local to give a temporary value to a package variable, especially a special variable. For example, this is perfectly sane code:

      my $slurp_file = do { local $/; # slurp mode... <SOME_HANDLE>; };
      This works because the setting for $/ (a global variable) will be affected for only the duration of the block in which the local appears: just long enough to get the value.

      So, it's not never use local, but rather, be sure you know when to use it (rarely) and when not to use it (mostly).

      -- Randal L. Schwartz, Perl hacker

Re: nuances of my, and maybe local
by rir (Vicar) on Sep 27, 2002 at 19:26 UTC
    local is global for awhile

    local gives a value to a global variable.
    While the localization is in effect the original value
    is unavailable. When it ends the old value is restored.

    Update: Value is the wrong word above. The technical
    term is thingie. local attaches the name to another
    thingie for a while

    my creates a new variable which may incidentally
    have the same name as a global variable. This is the common
    type of declaration as in C or C++.

    Usually you want to use my.

    You can't my %hash; local %hash; but
    it is possible to my %hash; local $hash{key} = 1000;
    I haven't used or examined this usage though.

    I don't, GASP, have perl on this machine, so this is untested, but will demonstrate the important differences
    between lexical and dynamic scoping.

    $var =1; { my $var = 2; print "\$main::var >$main::var<\n"; print "\$var >$var<\n"; &show_var; # my var doesn't exist outside this scope } { local $var = 3; # local var gives $main::var a temporary value print "\$main::var >$main::var<\n"; print "\$var >$var<\n"; &show_var; # local var ceases to exist when we _leave_ this scope } print "\$var >$var<\n"; sub showvar { print "showvar($var)\n"; }
Re: nuances of my, and maybe local
by samurai (Monk) on Sep 27, 2002 at 17:20 UTC
    To answer your question on local, it makes a temporary copy of a higher-scoped variable. For example:

    my $fred = "foo"; for (my $idx = 1; $idx <= 10; $idx++) { local $fred; $fred = $fred x $idx; print $fred, "\n" # foo, foofoo, foofoofoo... } print $fred, "\n"; # foo

    So once your for loop is done, even though you kept modifying fred each time, at the end of the loop, fred is still "foo".

    EDIT: Apparently my understanding of local was not correct. Live and learn. If somone would delete this post I would appreciate it.

      Samurai, local() operates on things that live in the symbol table - lexicals don't and you can't local()ize a lexical. You *can* use nested my() calls but that's almost always the wrong thing.

      # This prints: # Lexicals: 12 # Globals: 34 use strict; # nested my() example my $lex = 1; { # local $lex; this line is a syntax error my $lex = 2; print "Lexicals: $lex "; } print "$lex\n"; # local()ized global our $global = 3; { local $global; $global = 4; print "Globals: $global "; } print "$global\n";
      local works on package variables and lexical hash elements only.
      my $foo; local $foo # WRONG my %foo; local %foo; # WRONG my %foo; local $foo{key} = 'value'; # OK use vars qw ($var); $var=5; local $var = 10; # OK


      -Lee

      "To be civilized is to deny one's nature."
        Wrong.

        local doesn't care whether the hash is lexical, it can replace array elements, and the only reason it doesn't work on lexical variables is that Larry ruled that too confusing.

      I tried to run that code, and got:
      ./test.pl Can't localize lexical variable $fred at ./test.pl line 7. Exit 255
      my $fred = "foo"; for (my $idx = 1; $idx <= 10; $idx++) { #Changed this line to my my $fred = "blah"; # $fred = $fred x $idx; print $fred, "\n" # foo, foofoo, foofoofoo... } print $fred, "\n"; # foo

      Outputs:
      ./test.pl blah blahblah blahblahblah blahblahblahblah blahblahblahblahblah blahblahblahblahblahblah blahblahblahblahblahblahblah blahblahblahblahblahblahblahblah blahblahblahblahblahblahblahblahblah blahblahblahblahblahblahblahblahblahblah foo
      So it looks like my will at least hide the value of the outer scope's version of $fred. More confusion, I have not read the links below yet.....

      Thanks!