develooper Front page | perl.perl5.porters | Postings from September 2013

Re: [perl #120047] perl should enable "$_" for use before callingsubs

Thread Previous | Thread Next
From:
Aristotle Pagaltzis
Date:
September 29, 2013 12:57
Subject:
Re: [perl #120047] perl should enable "$_" for use before callingsubs
Message ID:
20130929125713.GA12288@fernweh.plasmasturm.org
* Linda Walsh <perlbug-followup@perl.org> [2013-09-29 11:30]:
> Instead, when $_ is aliased to a constant, when code control exits the
> lexical scope of the for loop by calling funcs outside of the loop,
> the readonly status of $_ needs to be "noted" and saved as part of the
> current context. In subroutines, though they need to be able to use $_
> "normally", or it places an undo and unnecessary constraing on those
> developing libraries. They don't know where they will be called from,
> thus, one could argue that any code that is "called" cannot use "$_".
> This places a large handicap on all "called code". Any modifications
> done to "$_" in sub functions would be ignored upon return to the
> lexical scope where $_ was read-only.
>
> It is the case that various "builtin"s already do this.

I will assume you are referring to map, grep and foreach here, because
I do not know what you could be talking about otherwise. It would help
if you were explicit and specific, however.

> So one would be hard pressed to find a case where builtin's can do it
> (can in turn call other subs where now "$_" is no longer R/O), but not
> allow user-level code that that tries to use $_ ideomatically, but
> magically fails due to $_ being protected.

Au contraire, one can find such cases very easily when one understands
why some do and others don’t.

The reason is that map, grep, foreach do this because they alias $_ to
another scalar, rather than changing the contents of the scalar $_ was
previously pointing to. There are plenty of other builtins, namely any
that do *not* alias $_ but instead modify its contents, which *will*
trigger a read-only value modification exception if you invoke them
while $_ refers to a read-only scalar.

There is no arbitrariness as to why user code happens to not get that
behaviour either because user-level code *is* able to do the same, by
either localising or aliasing $_ itself:

    sub with_local {
        local $_ = $some_modifiable_value;
        # doesn't matter here what $_ was set to before
        # it's now a copy of $some_modifiable_value
    } # and now $_ is back to whatever it was before

    sub with_foreach {
        for ($some_modifiable_value) {
            # doesn't matter here what $_ was set to before
            # it's now the same as $some_modifiable_value
        } # and now $_ is back to whatever it was before
    }

The difference between these is that localising means you’ll be changing
a copy of $some_modifiable_value, so any modifications to $_ will not be
reflected in that variable. Aliasing means you are literally making $_
refer to the same scalar as $some_modifiable_value, and therefore any
changes to either one will be reflected in the other – just like map,
grep and foreach do. (Well, you are literally using foreach to get the
aliasing, of course.)

> Regardless of documenation that may justify this behavior, I would
> like to see the design reasons for this behavior if such is to be
> found.

The design reason is that a user subroutine may well be interested in
the value that was previously in $_, even if that was a read-only value.
The language has no way to know what the user intended so it doesn’t try
to, as well it oughtn’t.

> I see no logic in disabling $_, **randomly*** (based on callstack) in
> a sub-function or library call but allowing it for built-ins.  There
> are things that can't be done without extraneous declarations without
> using the $_ register (like a postfix for-loop).
>
> Can this oversite be fixed?

Just because you cannot see a reason does not automatically mean that
there cannot be any and that this must therefore be an oversight (or
else an arbitrary exercise of power, whenever you are not feeling so
charitable). There *is* another option, that you may be overlooking or
simply misunderstanding something.

> Can people not make stuff up as to why it can't or shouldn't be done
> as was done when I suggested allowing explicitly declared local vars
> […]

This is part of another ticket and off-topic in this one.

Regards,
-- 
Aristotle Pagaltzis // <http://plasmasturm.org/>

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About