Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much

a rule of thumb for $_ in Perl

by apotheon (Deacon)
on Oct 01, 2007 at 21:05 UTC ( #641994=perlmeditation: print w/replies, xml ) Need Help??

Disclaimer: This is my opinion. It doesn't have to be yours. I do not claim to speak for the Perl community as a whole in this regard.

Perl makes use of an implicit scalar variable, $_. The $_ variable is assigned a value whenever you write code that requires a scalar value to be passed to something without actually passing it explicitly. For instance, if the first line of your foreach loop looks like this:

foreach (@foo) {

. . . you're going to get each element of @foo being available to the code executed inside the loop, one iteration at a time, in the $_ variable. As such, you might write code like this:

foreach (@foo) { print $_; }

Let's ignore for the moment that you could, with a very simple loop like that, put the print part before the foreach part, all on one line, and skip the braces entirely. Itís 'just a bit of very simple example code.

Anyway . . . a lot of people find $_ ugly and even obfuscatory. The answer for most is to always avoid $_ at all costs. Some even take that to the unreasonable extreme of avoiding Perl, as if the entire language is tainted by their personal distaste for the $_ variable. In the case of continuing to use Perl while avoiding $_, however, you might end up with code like this:

foreach $bar (@foo) { print $bar; }

This way, you can name your iterator scalar descriptively, clarifying the code. I absolutely agree that this is an excellent approach to take — but I also believe there are times that the inclusion of the $_ variable in the Perl language can provide some benefits, not only for the coder, but for whoever has to read the code again later. The key is that you should never have to actually type the dollar and underscore characters to access that variable's contents. You could, for instance, do this:

foreach (@foo) { print; }

That is the sort of behavior that makes it possible for a Perlist to do things like print foreach @foo;, in fact — which can add even more clarity to your code when the contents of your loop consist of a single (short) line of code. Just remember, when dealing with Perl, that $_ is an implicit variable, and should only be used implicitly (if at all possible to avoid explicit use). When the code in your loop (or wherever else you are using $_, whether you use it explicitly or implicitly) is brief enough, consider whether implicit use of $_ would clarify your code. If it wouldn't, or you basically can't use it with your code as written, consider whether one of the following is true:

  1. You should probably avoid using $_ there, and use a different, explicit variable instead.
  2. Your code might benefit from a little refactoring so that use of an implicit variable would help clarify things.

In other words, the rule of thumb for $_ in Perl is as follows:

If you have to use it explicitly, use something else instead.

That rule of thumb is not just "never use it". It's there for a reason.

(NOTE: crossposted)

print substr("Just another Perl hacker", 0, -2);
- apotheon
CopyWrite Chad Perrin

Replies are listed 'Best First'.
Re: a rule of thumb for $_ in Perl
by kyle (Abbot) on Oct 01, 2007 at 21:16 UTC

      This is one of the biggest fault with Perl, a language shoudl be clear and easy, if the language requires people to remember the list of functions realting to $_, it is pure stupid.

      You don't recite poet, but write better poet.

        Perl does not require anyone to remember the list of functions that use $_ as a default any more than C requires one to remember the list of functions that take a file number as an argument. These things are very well documented. I used split successfully for years without knowing what its default arguments were, and if I'd ever seen it in foreign code (probably where I learned it, in fact), it's clearly documented.

        Actually, you need to remember only those few functions that put information in $_ (like map, grep, foreach, commandline -n etc); not those lots of functions that _optionally_ default on $_ (like print, split, m//, sin, unlink) because for these you can just always use these with an explicit argument.

        Its certainly your opinion, and not of several other extremely good perl programmers.
        print foreach @list_of_items
        is quite an concise and more readable than most other code i've seen that does the same thing. Like the blog says, its up to you to use it wisely, use it enhance your code or use it make your code look like a junkie on meth. Up to you, really.
Re: a rule of thumb for $_ in Perl
by TGI (Parson) on Oct 02, 2007 at 20:02 UTC

    I agree with you general sentiment. IMO $_ should be used to increase readability. For the most part explicit use of $_ is a detriment to readability.

    For example, I will use $_ explicitly when I would otherwise be creating a throwaway variable:

    foreach ( @array_of_array_refs ) { my @current_array = @$_; # do some destructive processing on @current_array } #compare to foreach my $current_array_ref ( @array_of_array_refs ) { my @current_array = @$current_array_ref; # do some destructive processing on @current_array }

    I feel believe that this helps reduce visual noise, and keeps the code focused on what is important. Unpacking $_ to a scalar may be used to avoid side effects due to the aliasing of loop variables.

    TGI says moo

Re: a rule of thumb for $_ in Perl
by ambrus (Abbot) on Oct 02, 2007 at 07:03 UTC

    I wonder if you use map or write your own sub map_alike { my $f = shift; map { &$f($_) } @_; }.

      Why the heck would I write that map_alike subroutine?

      print substr("Just another Perl hacker", 0, -2);
      - apotheon
      CopyWrite Chad Perrin

Re: a rule of thumb for $_ in Perl
by Cop on Oct 02, 2007 at 02:59 UTC

    To avoid Perl because of $_ is rather extreme, and I am not surfe anybody actually think that way. It's like you don't avoid a language because it supports goto. Most of the ordinary people, and also every wise people usually only use a subset of teh language that is sufficient their needs, and I never liked $_ that much, and never care to use it.

    Not care to use it is different from avoid it. You avoid it because of fear, but you don't care to use it because you look down on it.

    If one is confident in himself, he can chose to use anything. What's wrong with $_, I always use it with read file, but that's it.

    If a language supports goto I will use it, if I need to say something like:

    abc: read key board input; process if not quit goto abc

    clear straight and easy to read and understand.

    of course you can always say:

    while True: line = raw_input() if line == "quit": break

    Worls too, and nothign wrong with neither.

    Good luck and good night.

      Sorry, but I think that way. Reading peoples code who'd used $_, and $` and $' and ... Just go away and die, Perl. I learned Python, then Ruby. The one thing I value above all is clarity, and _for_ _me_, Perl just doesn't cut it. Having said that, the article did prompt me to maybe look again.
        Oh, and whilst I'm sure there's a "goto" in C, and many other of the languages I've coded in, I've never even wanted to use one. Dunno what that says about my code - inflexible, too complex - I hope not. Clarity is first and last in coding.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://641994]
Approved by ikegami
Front-paged by Old_Gray_Bear
and the radiator hisses contentedly...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (4)
As of 2018-05-27 05:46 GMT
Find Nodes?
    Voting Booth?