Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re^2: Playing with non-localized $_ in nested loops.

by davido (Cardinal)
on Aug 23, 2004 at 02:13 UTC ( [id://385000]=note: print w/replies, xml ) Need Help??


in reply to Re: Playing with non-localized $_ in nested loops.
in thread Playing with non-localized $_ in nested loops.

gaal,
I read the slides from your lightning talk. They were interesting. One thing that I might add (or otherwise comment on) is the suggestion that while() doesn't localize $_. While this is true, it's probably more accurate to state that <FH>; doesn't localize $_. Because the fact is that while() isn't itself acting on $_. The action is carried out by the diamond operator implicitly spilling its guts into $_. while() doesn't really have much to do with it, though we get in the habbit of thinking that it does since the while( <> ) construct is so common, and since foreach loops default to acting upon $_.

Also commenting on your slides (not having heard the lecture), foreach is the exception as you said, but this is because foreach works in an entirely different way than while(). With respect to foreach, it is the loop construct itself that acts upon $_, in a very special way. We even write it in a very special way (if we write it out longhand):

foreach $_ ( list )

...that's how foreach deparses with B::Deparse. Your slides mention that foreach is the exception. While it is an exception, it is not the only one. map also is a looping mechanism where $_ is localized. Consider the following code:

$_ = "Test string\n"; my @array = map { $_ = chr $_ } 32 .. 64; print $_; __OUTPUT__ Test string

As you can see, the use of $_ inside of map works a lot like the iterator of a foreach loop, in that it serves as an alias to the elements of the input list (ok, my example doesn't demonstrate this, but it's true), and in that it is localized (my snippet shows this to be the case).

Just a few observations and additional meditations... ;)


Dave

Replies are listed 'Best First'.
Re^3: Playing with non-localized $_ in nested loops.
by ysth (Canon) on Aug 23, 2004 at 04:22 UTC
    The automatic setting of $_ comes from the combination of while() and readline. Just a plain readline won't do it. Nor does while with just any operator do the implicit assignment.
      <DATA>; print $_; __DATA__ This is a test. __OUTPUT__ Use of uninitialized value in print at mytest.pl line 8, <DATA> line 1 +.

      Hmm... You're right. There goes that theory. ;) I was erroneously sure that the while() loop's conditional had nothing to do with the fact that the diamond operator feeds $_. Thanks for the enlightenment. :D


      Dave

        There are actually two pieces of dwimmery going on; first, if a readline or a glob is the only thing in a while condition (whether a statement modifier or while statement), it gets an implicit $_ =. Next, if a while condition is a scalar assignment from a readline, readdir, glob, or each, the whole condition gets an implicit defined() wrapped around it, so the loop continues on "0" or "".

        That is why, in the node you referenced, I was talking about while(<FH>). Invoking the DWIMmery really does require this entire combination of operations.

        Makeshifts last the longest.

Re^3: Playing with non-localized $_ in nested loops.
by gaal (Parson) on Aug 23, 2004 at 06:18 UTC
    for, map, and grep: these three constructs localize $_. But in fact, map and grep are more vulnerable than foreach, because they don't give you the choice of using a lexical as your aliased iterator (iterant?). I did mention this in the talk though I guess the emphasis is stronger when you have more than the slides :)

      There is a difference between localizing $_ and aliasing it to something else. Do not confuse the two.

      Note also that there is no construct which implicitly localizes $_, but there are several which alias it to something else.

      Obviously, while(<FH>) cannot alias the variable to anything, because one would have to be able to expect that modifying $_ would actually modify the file. Instead, readline returns a copy of the data found in the file.

      It really is obvious and very consistent if you think about it. Perl just DWIMs well enough in so many cases that it's easy to overlook some of the ramifications of any single operation.

      Makeshifts last the longest.

        The aliasing is local to the scope of these constructs, so why is it confusing things to say that the constructs localize $_?

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (7)
As of 2024-04-19 15:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found