当尝试在Perl中的一个操作中分配变量并测试它的定义时,例如在if
的条件下有用,我写起来似乎很自然: / p>
if ( defined my $thing = $object->get_thing ) {
$thing->do_something;
}
就我的理解而言,defined
的优先级为rightward list operator,低于赋值的优先级,因此我希望上面的代码等同于:
if ( defined ( my $thing = $object->get_thing ) ) {
$thing->do_something;
}
虽然后者,带括号的代码确实有效,但前者会产生以下致命错误:"无法在标量赋值中修改定义的运算符"。
添加括号并不是什么大不了的事,但我很想理解为什么第一个版本不起作用,例如什么样的事情" defined
是什么,它的优先级是什么?
答案 0 :(得分:10)
命名运算符分为一元运算符(总是只占一个操作数的运算符)和列表运算符(其他所有) [1]
defined
和my
[2] 是一元运算符,其优先级高于其他命名运算符。
sub也是如此,所以我将用它们来演示。
$ perl -MO=Deparse,-p -e'sub f :lvalue {} sub g :lvalue {} f g $x = 123;'
sub f : lvalue { }
sub g : lvalue { }
f(g(($x = 123)));
-e syntax OK
$ perl -MO=Deparse,-p -e'sub f($) :lvalue {} sub g($) :lvalue {} f g $x = 123;'
sub f ($) : lvalue { }
sub g ($) : lvalue { }
(f(g($x)) = 123);
-e syntax OK
但当然,defined
不是左值函数,因此在赋值的LHS上找到它会导致错误。
and
,or
,not
,xor
,lt
,le
,gt
,{{ 1}},ge
,eq
和ne
不被视为命名运算符。
cmp
非常不寻常。除了具有编译时和运行时效果之外,其语法还取决于是否在其参数周围使用了parens。没有parens,它是一个一元的运营商。对于parens,它是一个列表操作符。