ok, that works, thanks.
But it leaves me worried that $_ is being used in say() as a global...
...or am I needlessly worried here? All the best practices talk about not using $_ since it's a global, and your suggestion uses $_. So the question is, is that $_ referenced in the say() sub a global from the implicit $_ in the mainline loop, or not...? | [reply] |
But it leaves me worried that $_ is being used in say() as a global...
You can't "use as a global", you can just "use a global", and you're the one who asked to use $_.
So the question is, is that $_ referenced in the say() sub a global from the implicit $_ in the mainline loop, or not...?
Yes, because $_ is a global. Actually, it's a "super global", meaning "$_" refers to the same variable ($::_) no matter which package you're in.
Note: It is possible to make $_ a lexical, but that feature was also introduced in 5.10, it's experimental, and I don't think it will survive. (A step was already taken by core to avoid using it.)
So what you get is:
BEGIN {
if ($] < 5.010) {
*say = sub { local $\ = "\n"; print @_ ? @_ : $_ };
} else {
require feature;
feature->import('say');
}
}
There's probably a module that does that.
| [reply] [d/l] [select] |
But it leaves me worried that $_ is being used in say() as a global...
That's what $_ is; a global; and it's exactly what the real say does, along with a raft of other built-ins.
But it's a read-only reference, so it cannot harm anything.
So the question is, is that $_ referenced in the say() sub a global from the implicit $_ in the mainline loop, or not...?
I cannot parse the highlighted bit of that sentence.
Perhaps this will satisfy: There is only one $_ at any given time. It is the global $_.
Sometimes it is localised implicitely by some constructs (eg. for, while) and sometimes explicitly by user code; but all that means is that a copy of the previous value is kept somewhere and gets restored once the localisation ends.
Whenever you use $_; you get its current value, regardless of whether it has been localised in one or many previous scopes.
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
| [reply] |
OK, thanks. I hear what you're saying, but why does the use of a global in a function leave me feeling dirty?
Short of any other suggestions, this looks like the way to go.
Thanks
| [reply] |
The best practice of not using globals is like "don't use goto" or "don't do drugs" - the rule exists because the majority of people abuse them. This is one of the cases where you know what you are doing and why - you're not defining a new global, instead you want to use $_ for its intended purpose. So don't worry :-)
The only minor caveat about $_ might be if someone were using the experimental lexical $_, introduced in Perl 5.10 and made experimental due to various problems in 5.18:
sub foo { print "<$_>\n" }
for (qw/a b/) {
foo;
for my $_ (qw/x y/) {
foo;
}
}
__END__
Use of my $_ is experimental at - line 4.
<a>
<a>
<a>
<b>
<b>
<b>
But that's a case of "the user got what they were asking for", plus there's the warning about it being experimental.
P.S. Have you seen Perl6::Say and Say::Compat? And by the way, the former simply does this in its source: @_ = $_ unless @_; | [reply] [d/l] [select] |