On 26/08/2011 18:12, Jim Gibson wrote:
On 8/25/11 Thu  Aug 25, 2011  5:20 PM, "Rob Dixon"<rob.di...@gmx.com scribbled:
On 25/08/2011 20:36, Shlomi Fish wrote:

If you want to use $_ so be it, but it can easily introduce
subtle errors into your code, because $_ is so easy to modify and
clobber. So I would recommend against these, and still think it's
a good idea.

Please substantiate this assertion. I believe your recommendation
deserves to be put in the bin of ill-conceived dogma.

Shlomi gave a link to a case where somebody had to find a subtle error
caused by $_ being clobbered. I would only disagree with Shlomi's use of the
term "easily". I hope we can all agree that $_ can be overwritten
inadvertently, but it does not happen very often.

Nevertheless, beginning Perl programmers should be cautioned that it can
happen, and they should be encouraged to use explicitly-named variables for
complex loops and blocks and especially for any block that calls a
subroutine or system function.

We need to respect the people who post here seeking help. They need to be
told about those Perl issues that are not obvious, such as $_ being
overwritten. They do not need to be told "never use $_ by default because it
can be overwritten". It is up to each programmer to choose whether or not to
use $_ as a default variable and risk it getting clobbered by mistake. They
do need the information on which to base this decision.

They also need to be encouraged to use "best practices". However, what
exactly best practices are is open to debate.

I believe the fragility of $_ is apocryphal, and Shlomi's insistence on
avoiding it is akin to remembering always to close the fridge door to
keep the elephants out. If nothing else, using named variables
everywhere adds noise to a program and makes it frustrating to read.

As Randal says, $_ is localized everywhere it is used implicitly by a
loop, including foreach, map and grep as well as the List::Util
functions, so I believe that corrupting it is rarely a problem in
practice. The significant exception is while loops, which do not
preserve $_ and so could be said to be prone to unexpected errors.

If I was to set rules, it would be that $_ should never be modified
either explicitly or by the condition in a while loop. The latter most
commonly appears in a read loop

  while (<$fh>) {
    :
  }

which is more safely written as

  while (my $record = <$fh>) {
    :
  }

especially now that the semantics of such a read loop now correctly
check the definedness of the data read, and is equivalent to

  while (defined(my $record = <$fh>)) {
    print $record;
  }

But I would be sad to rule against niceties like

  not /^#/ and print for <$fh>;

As an aside, the same applies to the common warning against using the
global values $a and $b 'because they are used by sort'. Once again,
sort localizes these variables within the comparison code so there is
very little chance of inadvertently modifying their values.

Overly-careful warnings can have the opposite of the desired effect,
especially on beginner programmers, and make it seem like the language
is rife with pitfalls and gotchas, especially when these apply to
ubiquitous core concepts like $_. I hope people will think twice about
the ideas that they are conveying.

Cheers all,

Rob

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to