http://qs321.pair.com?node_id=11120393


in reply to Shouldn't LITERAL references be readonly? (updated)

Both the hash constructor ({}) and the array constructor ([]) create a fresh variable and a fresh reference to it.

"TEST", 42 and undef do not create anything; they simply place a previously-constructed scalar on the stack. Changing these scalars would be bad, so they are protected from being changed.

For example, take the following code:

for (1..2) { for ((), 4..6) { say ++$_; } say ""; }

Before 5.20, it output the following:

5 6 7 6 7 8

That is something that isn't read-only but should be. If "TEST", 42 or undef weren't read-only, a similar problem would occur.[1]

There's no such problem with the newly created references from {} and []. {} and [] are akin to "<$x>" (also not read-only), not "TEST".


  1. It would be particularly bad if the scalar returned by undef wasn't read-only. That particular scalar (&PL_sv_undef) is used all over the place. For example, if ++undef didn't fail, it would cause read to start returning true on failure.

Replies are listed 'Best First'.
Re^2: Shouldn't references be readonly? (updated)
by LanX (Saint) on Aug 06, 2020 at 12:08 UTC
    my main point is that things like this

     map { ++$_ } [1,2,3]

    should throw an error, because the mutation of a reference itself doesn't make any sense.

    And I was asking if there is a reason why they don't.

    The whole discussion about "literals" is unfortunately only distracting,

    (though Wikipedia is on my side: Literal (computer programming): "a notation for representing a fixed value in source code" but I don't wanna continue this.

    NB: fixed doesn't mean (compile-time) constant. It means not variable)

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      The whole discussion about "literals" is unfortunately only distracting

      uh, I didn't bring up literals at all. It's an ambiguous word which may or may not include [4,5,6] depending on who you ask. It's useless to talk about literals.

      You asked why it wasn't like "TEST", 42 and undef, and I told you why.

      If you want to ask a different question now, fine.


      map { ++$_ } [1,2,3] should throw an error

      After all the fuss you made about inconsistency when you thought it wasn't consistent, you now want to make it inconsistent?

      No, assigning a number to a scalar that previously contained a reference is odd, but it shouldn't be an error.

        Ok, I'd like to contradict myself.

        I'd actually be ok with making "unassigned" scalars read-only. That includes [...], $x.$y, <>, etc.

        It might have performance implications, but they should be extremely tiny.

        It would break some code (such as my @lines = map { chomp; } <>;), but I think the benefits might be larger.