At 02:47 PM 4/22/2001, you wrote:
>i have read about it in 3 books and even used it in scripts i have made 
>but i still dont truly know how to be sure what $_ contains...can anyone 
>clear this up for me? Thanks
>Chris Brown

I think the best way to talk about $_ is to speak about it 
linguistically.  What $_ really is is a pronoun.  Think of it as 'it'.  For 
example:

while (<FILE>) {
     print;
}

In this case, you are using $_ without even mentioning it.  Perl looks at 
this and says "My programmer wants me to read a line out of a file and 
print (it) while there are still lines left to be read in the file 
FILE."  Perl's pretty smart like that.

We do this kind of thing all the time in English, talking about things 
without mentioning them.  For example the directions on the back of a 
bottle of shampoo.

Lather, rinse, repeat.

An assembly programmer wouldn't understand this unless you told them the 
following, because assembler languages have few ways to add context to 
statements.

Lather the shampoo into your hair, rinse the shampoo out of your hair, and 
then later the shampoo into your hair and rinse it out of your hair again, 
until your hair is clean, or you don't feel like doing it anymore.

You have to keep in mind that Perl was developed by a linguist, not a 
computer scientist.  Larry wanted to make sure that Perl had a lot of 
features that natural languages do. And one of these features is context.

You'll notice as you look through perlfunc that a lot of functions will 
work on $_ if you provide no argument to them.  This is how Perl lets you 
work in context.  If you don't tell it otherwise, Perl will work on 'it'. 
(or them, which is @_.)

A note about it's usage, though.  "Root of all evil"-type shouting matches 
aside, it's a useful construct, but there is nothing that says you MUST use 
it. (Aside from the grep and map functions, and perhaps a few other 
exceptions.) So, if you really don't like it, don't use it.  But I think 
you are missing out.

So whenever you find yourself doing something like this:

foreach my $line (@lines) {
     next if $line =~ /^#/;
     chomp $line;
     $line =~ s/stuff/things/;
     print $line;
}

consider saying this:

foreach (@lines) {
     next if /^#/;
     chomp;
     s/stuff/things/;
     print;
}

Also note, that in both instance next is using an implied default 
argument.  To fully qualify it, I should have labeled the loop with 
something like LINE: and say:

next LINE if $line =~ /^#/;

Context is cool.  : )

Thank you for your time,

Sean.

Reply via email to