| [reply] |
| [reply] [d/l] [select] |
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.
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] [select] |