http://www.perlmonks.org?node_id=1055805


in reply to Why doesn't Perl provide %_ as the hash equivalent of @_ in subs?

Another problem is aliasing. What should happen if you modify %_ keys ? %_ values?
  • Comment on Re: Why doesn't Perl provide %_ as the hash equivalent of @_ in subs?

Replies are listed 'Best First'.
Re^2: Why doesn't Perl provide %_ as the hash equivalent of @_ in subs?
by hippo (Bishop) on Sep 26, 2013 at 10:21 UTC

    Or if you modify @_, for that matter. Will we now have 2 copies of all the arguments with all the memory headaches that brings or will it be a reference (and how would that work)?

    For all the nice-to-haves such a feature might provide I think there are too many drawbacks and quite frankly the single-line "boilerplate" to achieve the same is no great hardship.

      "or will it be a reference (and how would that work)?"

      I don't know enough about how Perl implements arrays and hashes and about how tied hashes work, to answer that.

      But even if there's no good way to meaningfully allow modification of %_, that doesn't mean the magic variable should not be provided at all, it just means it should be read-only.

        It's possible to alias hash values.
        $ perl -MData::Alias -E' @_ = ( a=>4 ); alias %_ = @_; $_[1]=5; say $_{a}; $_{a}=6; say $_[1]; ' 5 6

        However, copying args is a good thing. That's why we don't access @_ directly.

        that doesn't mean the magic variable should not be provided at all, it just means it should be read-only.
        That looks like inconsistency to me.
        sub f1 { my ($x, $y) = @_; z($x, $y); }
        and
        sub f2 { z($_[0], $_[1]); }

        Above two examples are not identical. Later one is something low-level, and it's just asking for trouble (for example in cases like f2($1), f2($.) or f2($x, $x) when z() modifies arguments ).
        (NOTE: another common point of view is that caller of such functions is asking for trouble)

        Example:
        sub z { $_[0]++; print $_[1] } sub f1 { my ($x, $y) = @_; z($x, $y); } my $x = 4; f1($x, $x);
        prints 4
        sub z { $_[0]++; print $_[1] } sub f2 { z($_[0], $_[1]); } my $x = 4; f2($x, $x);
        prints 5

        So IMHO you should not use @_ just because it's shortest. Use it when you know what you're doing.

        And now you suggest add another %_ which behaves completely different way.

        Also making %_ readonly won't help much in cases when you pass magic variable as argument (example: RT#54728).