Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Re^7: What does my @x= (undef)x7; do?

by BrowserUk (Patriarch)
on Nov 10, 2015 at 17:58 UTC ( [id://1147377]=note: print w/replies, xml ) Need Help??


in reply to Re^6: What does my @x= (undef)x7; do?
in thread What does my @x= (undef)x7; do?

I assume the main point of confusion is the last case where only one of the elements get modified?


With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re^8: What does my @x= (undef)x7; do?
by AnomalousMonk (Archbishop) on Nov 10, 2015 at 18:42 UTC

    You assume too little confusion — always a mistake. Why, in the case of the  @b array, would nothing be changed in the aliased  @_ list? Each case more confusing than the other.


    Give a man a fish:  <%-{-{-{-<

      Why, in the case of the @b array, would nothing be changed in the aliased @_ list?

      Okay. Stepping through the problem.

      Starting with a populated array passed to a subroutine as a list and aliased into @_, means that the aliases (essentially references) in @_ simply point to the same place as the pointers to scalars in the array. Thus modifying the list through the aliases also modifies the array.

      Problem: if the array doesn't contain any pointers, what do you alias @_ to point at?

      Perl's solution appears to be to autovivify undef scalars in order to produce the list and it aliases those. But, it doesn't modify the array pointers to point at those scalars, so any modifications made via the aliasing disappear when the function returns and @_ is reclaimed from the stack.

      That also explains the @c result where you assigned undef to one element of the array, thus the corresponding element of the list can be aliased to an existing scalar and it therefore retains the modifications made inside the subroutine.

      With later versions of Perl, the undef's that are autovivified to produce the list are also set read-only. Whether that was a side-effect of the consting that took place around that time; or was a deliberate act to ensure that the previously silent loss of the modifications produced some diagnostic, I'm not sure; but either way I think it is the wrong solution because it creates a dichotomy.

      If you assign to a non-existent element of an array through a reference, a scalar is autovivified in that place:

      my @d; (\@d)->[3] = 2; pp\@d;; [undef, undef, undef, 2]

      And, IMO, a similar thing should happen when non-existent elements of an array are aliased by passing them to a subroutine.

      That is, instead of seeing that the array element being passed to the sub is non-existent, and autovivifying a read-only undef and aliasing that; Perl should autovivify a read-write scalar set to undef in the array and alias that to the subroutine.

      That would allow the arrays to be instantiated by either method and work consistently with each other and consistently with references.

      In the absence of that, then the non-existent elements should alias to a separate, stand-alone, global, manifest constant with magic attached, so that if any attempt is made to modify them, an appropriate error message can be produced.

      The current solution of autovivifying a read-only undef means a) the code wastes time allocating and initialising a bunch of scalars that it knows will be discarded; b) the error message produced is inappropriate and confusing.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
      In the absence of evidence, opinion is indistinguishable from prejudice.

        Thank you for your clear and complete reply. It illuminates questions I hadn't even realized existed until the advent of this thread.

        ... I think [the current solution] is the wrong solution because it creates a dichotomy.

        It also seems likely to create a few face-plants when people stumble over this little oddity.

        If you assign to a non-existent element of an array through a reference, a scalar is autovivified in that place ... And, IMO, a similar thing should happen when non-existent elements of an array are aliased by passing them to a subroutine.

        This is certainly the behavior I was expecting, and that I would consider most useful.

        Once again, thanks for this enlightening post.


        Give a man a fish:  <%-{-{-{-<

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1147377]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2024-04-16 05:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found