I always use @_[0]
to get the first parameter and use @_[1]
to get the second one. But when I search up code snippets online, I find many people like to use the shift
keyword. I don't find the shift
keyword being intuitive at all. Is there any functional differences between these two?
Asked
Active
Viewed 2,593 times
7

WSBT
- 33,033
- 18
- 128
- 133
-
6If you use `@_[0]` and `@_[1]`, you would get a warning saying it's better to use `$_[0]` and `$_[1]`. – ikegami Sep 27 '12 at 18:25
-
7Not using warnings is a horrible mistake. Never write code without both `use strict; use warnings;`. – TLP Sep 27 '12 at 19:15
-
Possible duplicate of [Is there a difference between Perl's shift versus assignment from @\_ for subroutine parameters?](http://stackoverflow.com/questions/415297/is-there-a-difference-between-perls-shift-versus-assignment-from-for-subrout) – Jonathan Hall Jan 14 '16 at 16:26
2 Answers
14
Yes, there is a difference between the two.
shift
would change the @_
(You could argue this would be an operation that would make shift slower)
$_[0]
or $_[1]
is just assignment and would not change @_
at all.
The aesthetic way of writing this is :
sub this_is_better {
my ( $foo, $bar, $hey, $whoa, $doll, $bugs ) = @_;
}

TJ B
- 157
- 7
-
-
2shift is not that much slower than simple assignment. It really depends on what you want to do. E.g., a common idiom is my $self = shift; my %args = @_; which removes the first element from @_ and dumps the remaining elements into a hash. – harleypig Sep 27 '12 at 18:23
-
2@user1032613: You specifically asked if there were any "functional differences"; you did not ask about "performance differences". If you meant the latter rather than the former, please update your question. (FWIW, I prefer the "aesthetic" way. +1) – Nemo Sep 27 '12 at 18:23
-
2As for performance, the Perl interpreter recognizes a number of patterns and handles them very efficiently. I would not be surprised if these were the same speed or if the "apparently slower" idiom were actually 10x faster. Write a test and measure if you care. – Nemo Sep 27 '12 at 18:26
-
2Performance is tricky. Perl 5.10.0 actually had a bug that made `shift` significantly faster than `my (...) = @_` (a list-assignment optimization accidentally got disabled). It was fixed in 5.10.1. – cjm Sep 27 '12 at 18:42
-
2With so many layers between your code and the machine, you can't guess at which operation is going to be faster. Remember to [benchmark before making performance pronouncements](https://gist.github.com/3795945), `my($foo) = @_` is one of the slowest ways to get arguments. `shift` and `$_[0]` are pretty much identical (`shift` is the fastest in 5.16 by a small margin) but its actually `my $foo` vs `my($foo)` which makes the difference. SURPRISE! **BUT** none of this matters, what you're doing in the subroutine is going to swamp any performance difference. – Schwern Sep 27 '12 at 19:28
0
As stated in the documentation, shift
without using an explicit array simply takes the next parameter from @_
in the subroutine locally by removing arguments from the beginning and shifting the remaining elements to the front.
-
2There is a functional difference ... shift modifies @_ while assignment does not. – harleypig Sep 27 '12 at 18:25
-
1@harleypig In a way it treats the array like a stack which is what I tried to explain toward the end. – squiguy Sep 27 '12 at 18:29
-
4Using "popping" is probably not a good idea in perl context, since `pop` actually removes an element from the *end* of the array. – TLP Sep 27 '12 at 19:14