Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Re: Should we Localize $_ ?

by bikeNomad (Priest)
on Jun 13, 2001 at 23:16 UTC ( [id://88169]=note: print w/replies, xml ) Need Help??


in reply to Should we Localize $_ ?

One of the reasons we don't see it often is that $_ is usually used in a context close to where it's set. So we see it used inside foreach loops, inside of <> constructs, etc. Usage of $_ is rare (in my experience) outside of an explicit context that sets it. You'd have to be calling a subroutine that modifies $_ without providing a context that sets it to have a problem like this.

Replies are listed 'Best First'.
Reii: Should we Localize $_ ?
by John M. Dlugosz (Monsignor) on Jun 13, 2001 at 23:32 UTC
    I don't see any difference between "modifying" and "setting" $_. If the sub called a a built-in that returns a result in $_ (like magic while(<>)), it will clobber the value in the caller's foreach.

    If the sub aliased it, using local or something like foreach which I assumes rebinds without changing the value, that would indeed be different.

    I'm supposing that the reason I don't see this as a problem in real scripts is that I don't use the implicit loop with nontrivial bodies—I name the iteration variable. I suppose people who heavily use map might get bit with it more.

    —John

      I don't get what you're saying. If you have a construct like while (<>) or foreach(@arr) you get a newly scoped $_:
      sub doit { my @array = qw(1 2 3 4); # this doesn't damage outer @array: $_ = 'xyz' foreach (@array); } my @array = qw(a b c d); print join("|", @array), "\n"; foreach (@array) { my $f = doit('abcd'); } print join("|", @array), "\n";
        Try the following with and without the 'local $_;' line and you'll see what he's talking about.

        use strict; sub getfile { local $_; my $filename = shift; local *F; open F, "< $filename" or die "Couldn't open `$filename': $!"; my $contents; while (<F>) { s/#.*//; # Remove comments next unless /\S/; # Skip blank lines $contents .= $_; # Save current (nonblank) line } return $contents; } my @array = ("base_tester", "Foo.pm"); foreach (@array) { my $filename = $_; my $f = getfile($filename); } print "@array\n";
        That's what I tried to see the effects, and I was rather surprised.
        No, while(<>) does not create a newly scoped $_.

        Behold:

        require 5.6.1; use strict; use warnings; my @array= (1,2,3,4,5); foo() foreach (@array); print "@array\n"; sub foo { while (<DATA>) { return } # silly, but makes a small example with little input. } __DATA__ clobbered clobbered clobbered clobbered clobbered

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (3)
As of 2024-04-25 09:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found