Purl Gurl said:
Not localizing $element is illogical and leads to
confusion until a person realizes it is, de facto,
the perl core default $_ variable.
This is an odd statement, because they ARE localized.
perlsyn sayeth:
The foreach loop iterates over a normal list value and sets the
variable VAR to be each element of the list in turn. The
variable is implicitly local to the loop and regains its former
value upon exiting the loop.
Local variables perpetuate to inner scopes, but their outer values are
restored when the inner scope is exited. In fact, that's the
definition of local. However, I will fully agree that this is one of
those "hidden features" that doesn't make sense until you are aware
that it exists, and why it was done that way. Especially considering
that most "best practices" discourage the use of local(), and yet here
we have it built into the language.
Why was it done that way? I think the reasons have been pretty well
illustrated by you, me, and everyone else. If you won't buy my
explanation, maybe you'll buy Larry Wall's, who so quoth a few years
back:
"...you'd have subroutines tromping each other's $_ variables all over
the place if they didn't clean up after themselves....(snip)
This is just another one of those cases where you have to design a
language in its own context, and not be too beholden to how other
languages do it. Your language can't be totally intuitive to everyone
all the time, because everyone is coming from a slightly different
linguistic background. Whether you spell it omelet or omelette, you
still have break eggs to make it."
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&[email protected]
The problem actually comes from the existence of $_ itself, which you
could also consider dubious. If you didn't create the variable, then
how would you intuitively know whether it's scoped globally,
lexically, or dynamically? And the answer is, you can't know unless
you have educated yourself on what it means in each context -
admittedly not a transparent task. If you don't want to do that, you
don't have to use $_. In fact, for exactly this reason, I usually
avoid using $_ except when the context is unmistakable.
But all these things being true, $_ is still not an alias for a
defined loop variable, the two never co-exist in the same scopes, and
their behavior is predictable if you understand that they are scoped
as though they had been declared using local().