请解释perl运营商关联性

时间:2017-04-10 11:40:33

标签: perl

DOC解释了perl运算符的优先级和关联性。我对->*运营商感兴趣。两者都有left关联性。

我有下一个例子,似乎->具有正确的关联性。 未保留作为文档说明:

my @args;
sub call { print "call\n"; shift @args }
sub test { print "test\n"; 1 }
sub t4 { print "t4\n"; 4 }

@args=( \&test, 2, 3 );
call()->( @args, t4 );


sub m1 { print "m1\n"; 2 }
sub m2 { print "m2\n"; 4 }

m1()*(@args, m2);

输出结果为:

t4
call
test
m1
m2

由于->已离开关联,我希望下一个输出:

call
t4
test
m1
m2

我错过了什么?为什么在t4之前调用call

3 个答案:

答案 0 :(得分:4)

您询问操作数评估顺序(评估操作数的顺序),而不是操作员关联性(同一运算符的运算符的顺序)评估优先级。)

许多运营商(包括->)的操作数评估顺序未定义(或至少未记录)。你会发现它是一致的,但不应该依赖它。

您可以使用语句中断强制所需的顺序:

my $sub = call();
$sub->( @args, t4 );

这也有效:

$_->( @args, t4 ) for call();

运营商相关性

关联性是评估相同优先级的运算符的顺序。

例如,*/具有相同的优先级,因此关联性决定了

 3 / 4 * 5 * 6

相当于

 ( ( 3 / 4 ) * 5 ) * 6 = 22.5

而不是

 3 / ( 4 * ( 5 * 6 ) ) = 0.025

如您所见,关联性可以直接影响表达式的结果。

操作数评估订单

操作数评估顺序是评估操作数的顺序。

例如,操作数评估顺序确定1+2之前是否评估3+4,反之亦然

( 1 + 2 ) * ( 3 + 4 )

除非评估操作数有副作用(例如更改变量或打印到屏幕),否则操作数评估顺序对表达式的结果没有影响。因此,某些语言未定义以允许优化。

在Perl中,对于许多运营商来说,它是未定义的(或至少是未记录的)。它仅记录以下内容:

  • 逗号运算符(,=>):从左到右
  • 二元布尔运算符(andor&&||//):左,然后可能正确 [1] < / SUP>
  • 条件运算符(? :):左,然后是第二或第三 [1]
  • 列表和标量赋值运算符(=):右,然后左 [2]
  • 绑定操作符(=~!~):左,然后右 [3]
  1. 需要进行短路评估。
  2. my $x = $x;
  3. 必填
  4. 要求完全运作。

答案 1 :(得分:3)

关联性是一条规则,它告诉您如何解析同一运算符出现两次的表达式,或者出现多个具有相同优先级的运算符。例如,关联性确定:

foo()->bar()->baz()

相当于

(foo()->bar())->baz() # left associative

而不是

foo()->(bar()->baz()) # right associative

由于您的代码只包含一个->运算符,因此该运算符的关联性无关紧要。

您似乎正在寻找有关->运算符的操作数评估顺序的规则。据我所知,perl中的大多数运算符都没有保证的评估顺序(很像C)。如果顺序很重要,您应该使用显式临时变量将表达式拆分为多个语句:

my $tmp = call();
$tmp->( @args, t4 );

答案 2 :(得分:2)

Associativity描述了处理相同优先级的多个运算符的顺序。它与是否先处理左参数或右参数无关。 ->左关联意味着a->b->c被处理为(a->b)->c,而不是a->(b->c)