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

LanX has asked for the wisdom of the Perl Monks concerning the following question:

Hi

could someone please point me to documentation giving insight about hash-values being lvalues which can be aliased?

DB<126> @h{1..5}=(1..5);\%h => { 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5 } DB<127> $_++ for %h DB<128> \%h => { 1 => 2, 2 => 3, 3 => 4, 4 => 5, 5 => 6 } DB<129> sub tst { $_++ for @_ } DB<130> @h{1..5}=(1..5);\%h => { 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5 } DB<131> tst(%h) DB<132> \%h => { 1 => 2, 2 => 3, 3 => 4, 4 => 5, 5 => 6 }

Cheers Rolf

Replies are listed 'Best First'.
Re: Alias of hash-values?
by moritz (Cardinal) on Feb 20, 2013 at 16:22 UTC

    Well, if hash values weren't lvalues, $h{1} = 2 wouldn't work. There's no reason why they shouldn't be lvalues when using the whole hash in list context. And any lvalues can be aliased, otherwise $_++ for ... could never work.

    I'm not sure those things are explicitly documented somewhere.

    The thing that surprises me though is that trying to increment the hash keys doesn't die like this one:

    $ perl -wE 'my $x; $_++ for ($x, 1)' Modification of a read-only value attempted at -e line 1.
      The thing that surprises me though is that trying to increment the hash keys doesn't die like this one:

      I agree, it seems odd. Consider:

      #! perl use strict; use warnings; use Data::Dump; my %h = (1 => 'Fred'); dd %h; fn(%h); dd %h; sub fn { print "BEGIN fn()\n"; dd @_; $_[0]++; $_[1] = 'Barney'; dd @_; print "-END- fn()\n"; }

      Output:

      12:02 >perl 541_SoPW.pl (1, "Fred") BEGIN fn() (1, "Fred") (2, "Barney") -END- fn() (1, "Barney") 12:02 >

      The hash value is clearly aliased, since the assignment in sub fn persists in %h after the sub returns. But the hash key is not: it appears to be copied (passed by value), as $_[0] behaves as a variable local to sub fn. (Whereas a literal value like 42 or 'Wilma' is aliased, as evidenced by the Modification of a read-only value error message which results from trying to increment it or assign to it within the sub.)

      An anomaly? Or a feature?

      Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

        We had the discussion about "aliasing read-only falling back to copy" not long a year ago.

        ref to read-only alias ... why?

        Apparently it also depends on the perl-version, threading and optimization ...

        Cheers Rolf

      > The thing that surprises me though is that trying to increment the hash keys doesn't die like this one:

      Yeah, that was an implicit question.

      So anything which is an lvalue in Perl can be aliased in foreach or @_ ?

      Cheers Rolf

        > So anything which is an lvalue in Perl can be aliased in foreach or @_ ?

        yep, seems to be the case!

        $a=41; sub tst :lvalue { $a } $_++ for tst(); print tst(); # prints 42

        Cheers Rolf