移位和解除引用操作符有问题

use*_*180 7 perl

我有一个关于如何->评估运算符左右两侧的问题.请考虑以下代码:

#! /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');
Run Code Online (Sandbox Code Playgroud)

输出:

u: CODE(0x324718), foo, bar
v: foo, bar
Run Code Online (Sandbox Code Playgroud)

我希望你和你的行为相同,但事实并非如此.在这些情况下,我总是假设perl评估了从左到右的事情.代码就像shift->another_method(@_)甚至shift->another_method(shift, 'stuff', @_)很常见.

如果第一个参数恰好是代码引用,为什么会中断?我在未定义/未记录的领域吗?

ike*_*ami 6

操作数评估顺序->()未记录.碰巧在LHS之前评估论点(分别在下面的3-4和5行).

>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
Run Code Online (Sandbox Code Playgroud)

在同一表达式中使用和修改变量都很危险.除非您能解释以下内容,否则最好避免使用它:

>perl -E"$i=5; say $i,++$i,$i"
666
Run Code Online (Sandbox Code Playgroud)

你可以用

$_[0]->(@_[1..$#_])
Run Code Online (Sandbox Code Playgroud)