'Why is `splice(@_, 0, shift)` safe?
The perl 5.18.2 documentation of splice has this example:
my(@a) = splice(@_,0,shift);
my(@b) = splice(@_,0,shift);
And I wonder:
If @_ is evaluated before the shift there would be one item too much for the result to be correct.
So conceptually the shift must be performed first.
However in C they teach you that you should never rely on a specific order of evaluation of actual parameters (shift modifies @_).
So is that code only working because @_ is passed as a reference (to be able to change it), and the shift being evaluated before splice can access @_?
A Bit of History
I found the example goes some way back to 1996 (at least) and the book (page 219; a comment on page 535 suggests it may even come along from Perl 4):
WALL, Larry, Tom CHRISTIANSEN und Randal L. SCHWARTZ, 1996. Programming Perl. 2. Sebastopol, CA 95472, U.S.A.: O’Reilly & Associates, Inc. ISBN 1-56592-149-6
Solution 1:[1]
Because @_ itself is being passed to the sub (rather than being flattened) because splice is expected to modify it. And Perl always passes by reference.
With a normal sub, @_ would get flattened. But being an operator, splice receives the array instead. And not a copy of it. Not only would that be inefficient, but splice is expected to modify it. So the array itself is placed on the stack. (In C terms, this is a pointer. All Perl variables are pointers. The fact that only pointers are being exchanged under the hood is why Perl exhibits pass-by-reference semantics.)
Perl evaluates lists from left to right, so @_ is placed on the stack, then 0 is placed on the stack, then shift is evaluated modifying @_ and placing the removed value on the stack.
It doesn't matter that @_ is modified when it's found on the stack. As long as these things happen before the splice is performed — and they are — it works perfectly fine.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
