in reply to "$_" vs. $_

In my opinion, $_ springs into being when Perl feels it's appropriate -- it's an auto-vivified rvalue.

On the other hand, $_ is *never* an lvalue unless you're using a regexp to modify the value, as in $_ =~ s/foo/bar/;, and even that's stretching a point, because of course uou can do the same thing with just s/foo/bar/;

So I would say that any code that *sets* $_ is, by definition, wrong.

Alex / talexb / Toronto

"Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

Replies are listed 'Best First'.
Re^2: "$_" vs. $_
by bsdz (Friar) on Apr 08, 2007 at 06:59 UTC
    So I would say that any code that *sets* $_ is, by definition, wrong.

    I feel this is not a Golden rule. Setting $_ has its uses, especially when one would like to do regex operations not wishing to declare intermediate variables. It is generally wise to localise $_ before setting it. A good example of this kind of usage can be found here.

      In the so-called good example, both local $_ could easily have been replaced with my. You gain the readability of a named variable at the tiny cost of having to specify the topic of two operations.

      my @a = map { s/\s*(#.*)?$//g; $_ } <DATA>; my @b; while (my $group = shift @a) { if ($group =~ m/\D(\d+)-(\d+)(?:\D|$)/) { my $range = "$1-$2"; foreach my $i ($1..$2) { (my $addr = $group) =~ s/(\D)$range(\D|$)/$1$i$2/; push @a, $addr; } } else { push @b, $group; } } print join("\n", @b);

      There are cases where using $_ helps, but I don't think this is one of them.

      Note: The localization of $1 and $2 is unnecessary. It's already being done by the for.

      Note: local $_ doesn't preserve $_ in all situations, unfortunately. for ($var) is a far better way of aliasing $_.

        Thank you for your point regarding unnecessary localization of $1 and $2. Still, my point was avoiding intermediate (possibly unnecessary?) variables, i.e. $addr and $group in your code that incredibly looks very much like my original!

        Ultimately, I guess it is style. One thing I love about Perl is TIMTOWTDI and I admit I tend to go for minimal keyboard presses unless extra performance is needed. Then, I would probably lean to doing it in C++.

        Update: Incidentally, the named approach is probably a little faster than a localised one. However, only slightly!

      A reply falls below the community's threshold of quality. You may see it by logging in.
Re^2: "$_" vs. $_
by mrpeabody (Friar) on Apr 09, 2007 at 03:25 UTC
    So I would say that any code that *sets* $_ is, by definition, wrong.
    Unnecessary, perhaps, but not wrong. Setting $_ can be useful:
    1. As a topicalizer in a single-item for loop, to make a series of operations on a common value read more cleanly.

      Instead of this:

      $h->{foo}{bar} =~ s/[._]/ /g; Some::Custom::Function($h->{foo}{bar}); $h->{foo}{bar} =~ s/^\s+//; $h->{foo}{bar} =~ s/\s+$//; $h->{foo}{bar} =~ s/`/'/g;
      You can write this:
      for ($h->{foo}{bar}) { s/[._]/ /g; Some::Custom::Function($_); s/^\s+//; s/\s+$//; s/`/'/g; };

    2. And the occasional weird circumstance, like conveniently modifying the values of a hash:
      map { $_ = foo( $bar, $_ ) } values %somehash;
    On the other hand, where real for loops are concerned, I find it reduces confusion to always provide your own lexical topic (e.g.  for my $key (@keys) { ... } ). A bit backwards from the way the language is designed, I suppose.
      Um, in both examples you are not setting $_---you are only modifying it.

      Small difference, but with it, I'd also say "never set $_".


      Search, Ask, Know
        Um, in both examples you are not setting $_---you are only modifying it.
        Interesting distinction. I think of them as synonyms, and would certainly argue that any statement that starts with "$_ =" is "setting" the variable. However, what name we use when giving a variable a new value is not really the point.

        What makes both of these examples useful is that they implicitly alias $_ to another variable before acting on it. That's where they differ from the OP's usage.