in reply to Re: Reliably simulating 5.10 say()
in thread Reliably simulating 5.10 say()

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...?

Replies are listed 'Best First'.
Re^3: Reliably simulating 5.10 say()
by ikegami (Patriarch) on Feb 08, 2015 at 15:34 UTC

    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.

Re^3: Reliably simulating 5.10 say()
by BrowserUk (Patriarch) on Feb 08, 2015 at 14:47 UTC
    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.
    "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
    In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked
      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
Re^3: Reliably simulating 5.10 say()
by Anonymous Monk on Feb 08, 2015 at 15:30 UTC

    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 @_;