Problems with the shift and dereference operator

I have a question about how the left and right sides of the operator are evaluated -> . Consider the following code:

 #! /usr/bin/perl use strict; use warnings; use feature ':5.10'; $, = ': '; $" = ', '; my $sub = sub { "@_" }; sub u { shift->(@_) } sub v { my $s = shift; $s->(@_) } say 'u', u($sub, 'foo', 'bar'); say 'v', v($sub, 'foo', 'bar'); 

Output:

 u: CODE(0x324718), foo, bar v: foo, bar 

I expect u and v to behave the same, but they do not. I always assumed that perl rated things from left to right in these situations. Code like shift->another_method(@_) and even shift->another_method(shift, 'stuff', @_) pretty common.

Why is this interrupted if the first argument is a code reference? Am I on undefined / undocumented territory here?

+7
perl
source share
1 answer

The procedure for evaluating operands ->() documented. This happens to evaluate the arguments before the LHS (lines 3-4 and 5 respectively below).

 >perl -MO=Concise,u,-exec a.pl main::u: 1 <;> nextstate(main 51 a.pl:11) v:%,*,&,x*,x&,x$,$,469762048 2 <0> pushmark s 3 <#> gv[*_] s 4 <1> rv2av[t2] lKM/3 5 <0> shift s* 6 <1> entersub[t3] KS/TARG,2 7 <1> leavesub[1 ref] K/REFC,1 a.pl syntax OK 

And using and changing a variable in one expression can be dangerous. It is better to avoid this if you cannot explain the following:

 >perl -E"$i=5; say $i,++$i,$i" 666 

you can use

 $_[0]->(@_[1..$#_]) 
+6
source share

All Articles