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


in reply to Re^6: Shouldn't references be readonly?
in thread Shouldn't LITERAL references be readonly? (updated)

I'm still waiting for someone to understand my question...

I understand it (I think) :-) The difference between map { $_++ } 1 failing and map { $_++ } [] not failing, or even map { $_++ } \1 not failing, is pretty clear to me. I just don't have an answer for you :-(

With [], I understand the arguments that it's a constructor, for example sub foo () { 1 } can be inlined, but sub bar () { [] } returns a new anonymous array each time. But something like map { $_++ } \undef or map { $_=3 } \1 not failing doesn't entirely make sense to me yet (note map { $$_++ } \undef does fail).

As an aside, I was playing around in the console a bit and can't yet wrap my head around this, it feels buggy, but that may just be because it's getting late here:

$ perl -wMstrict -MData::Dump -e 'dd $_ for map { $_++ } \undef' \undef $ perl -wMstrict -MData::Dump -e 'dd $_ for map { ++$_ } \undef' 94067726450329

Update: Nevermind, it clicked, d'oh. Also made a few minor edits to the above. Update 2: Oops, looks like my update came at just about the same time as your reply, sorry.

Replies are listed 'Best First'.
Re^8: Shouldn't references be readonly?
by Fletch (Bishop) on Aug 05, 2020 at 21:16 UTC

    The undef $_++ vs $$_++ I think the former is working because what's happening is:

    • An SVrv pointing to the SV* for undef is pushed on the arg stack
    • When map calls the EXPR $_++ that reference is getting numified, incremented, and that new int value stuck back into the SV* on the arg stack
    • Since it's a postincrement the map is returning the original value of $_ which is the ref to undef
    • The call stack goes away and with it the SV* which had the numified address plus one.

    In the second case you're explicitly dereferencing the SVrv to the constant undef and trying to increment that (which fails because undef is a singleton readonly SV*).

    Edit: And again yes making explanation by way of the implementation, but I think that's because knowing (sort of) how this is implemented under the covers makes these particular corner cases' behaviors not (as) surprising.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re^8: Shouldn't references be readonly?
by LanX (Saint) on Aug 05, 2020 at 21:11 UTC
    > I understand it :-)

    I wished I could up-vote you multiple times. :)

    > but sub bar () { [] } returns a new anonymous array each time.

    Interesting ... here a workaround

    DB<99> my $a =[]; sub bar () { $a } DB<100> sub tst { print bar,bar} DB<101> tst ARRAY(0x3365bc0)ARRAY(0x3365bc0)

    But sorry when I insist, the following case should be an error, because the aliased literal array will be destroyed afterwards, which sense does it make to alter it?

    map { $_++ } []

    I wouldn't mind map { $_+1 } [] tho.

    > But something like map { $_++ } \undef not failing doesn't entirely make sense to me yet

    agreed, I think it's simply not covered.

    > As an aside, I was playing around in the console a bit and can't yet wrap my head around this,

    ... is pretty clear to me. I also have an answer for you ;-p

    The first post -increment returns the original value before incrementing.

    The second pre -increment returns the result, which is the numification of the reference +1

    DB<105> p []+1 53924433

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