在语句中分配变量时,perl 中的三元运算符会产生意外结果
我正在尝试从 php 过渡到 perl,预计会遇到一些奇怪的情况。我无法理解为什么我的代码的一个版本比另一个版本有效。
这失败了:
sub tester
{
$return;
($_[0] < 10) ? $return = "youre a youngin" : $return = "youre an old person";
return $return;
}
print "how old are you?";
$a = <>;
chomp $a;
print tester($a); #both result in "youre an old person"
但是这个有效:
sub tester
{
return ($_[0] < 10) ? "youre a youngin" : "youre an old person";
}
print "how old are you?";
$a = <>;
chomp $a;
print tester($a);
这里真正的区别是什么?!
I'm trying to make a transition from php to perl and expectedly running into some weirdness. I cannot understand why one version of my code works vs another.
This fails:
sub tester
{
$return;
($_[0] < 10) ? $return = "youre a youngin" : $return = "youre an old person";
return $return;
}
print "how old are you?";
$a = <>;
chomp $a;
print tester($a); #both result in "youre an old person"
however this one works:
sub tester
{
return ($_[0] < 10) ? "youre a youngin" : "youre an old person";
}
print "how old are you?";
$a = <>;
chomp $a;
print tester($a);
what is the real difference here?!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这和Perl的运算符优先级有关。在 Perl 中,
相同
与注意括号绑定到 FRONT
。这导致了 Perl 的另一个令人困惑的特性:条件左值:你可以这样做
(CONDITION ? $ASSIGN_A_IF_CONDITION_IS_TRUE : $ASSIGN_B_IF_CONDITION_IS_FALSE) = 2
这是一个修复
http://codepad.org /MxBAy7wy
编辑:
但是,大多数人会写
,从而节省了键入的冗余变量两次。
根据 Perl 和 PHP 文档,Perl
?:
是右关联的,而 PHP?:
是左关联的。 (http://perldoc.perl.org/perlop.html)(http://php.net/manual/en/language.operators.precedence.php)It is related to Perl's operator precedence. In Perl,
is same as
notice the paren binds to the FRONT.
and this leads to another confusing feature of Perl: conditional lvalues: You can do this
(CONDITION ? $ASSIGN_A_IF_CONDITION_IS_TRUE : $ASSIGN_B_IF_CONDITION_IS_FALSE) = 2
Here is a fix
http://codepad.org/MxBAy7wy
EDIT:
However, most people would write
, saving the redundancy of typing the variable twice.
According to Perl and PHP docs, Perl
?:
is right-associative and PHP?:
is left-associative. (http://perldoc.perl.org/perlop.html ) (http://php.net/manual/en/language.operators.precedence.php )啊,您已经发现为什么
?:
是一个坏主意,除了在微不足道的情况下。运算符优先级是问题所在。您很可能想要这样做:
不过,您的代码还存在一些其他问题。
my
运算符显式执行此操作。使用严格
并使用警告
。这些编译指示禁用了古老的 Perl 恶作剧,并警告可能是错误的可疑操作。@_
;没有什么理由直接在函数中使用$_[0]
。 (这样做很危险,因为@_
是别名;您可以更改调用者的变量!)因此您可能想要更像这样的东西:
请注意
my $x = ...
声明单个变量并分配单个值,而my ($x, $y, $z) = ...
声明多个变量并将列表解包到其中。my
变量称为词法变量,仅存在于声明它们的块中;它们不像 PHP 变量那样具有函数作用域。实际上,您可能应该在 perlsub。Ah, you've discovered why
?:
is a bad idea except in trivial cases.Operator precedence is the problem. You most likely want to do this:
There are a few other issues with your code, though.
my
operator.use strict
anduse warnings
in Perl code. These pragmas disable ancient Perl shenanigans and warn about suspicious operations that might be bugs.@_
; there's very little reason to use$_[0]
directly in a function. (And it's dangerous to do so, since@_
is aliased; you could change the caller's variables!)So you probably want something more like this:
Note that
my $x = ...
declares a single variable and assigns a single value, whereasmy ($x, $y, $z) = ...
declares multiple variables and unpacks a list into them.my
variables are called lexical and only exist within the block where you declare them; they aren't function-scoped like PHP variables. Actually you should probably just read about them in perlsub.这是一个优先事项。
...效果更好。
但老实说,没有哪个认真的 Perl 程序员会这样写。首先,他们会将以下内容放在程序的顶部:
其次,他们会将参数放入本地:
第三,他们会以两种方式之一编写条件:
如果他们来自 Lisp 背景,他们可能会放弃使用 $return 变量并编写:
It's a precedence thing.
...works better.
But honestly, no serious Perl programmer would write it like this. First, they would put the following at the top of their program:
Second, they would put the argument into a local:
Third, they would write the conditional in one of two ways:
If they came from a Lisp background, they would probably dispense with the $return variable and just write:
如果你写:
那么你就会得到你期望的结果。
If you write:
then you get the result you expect.
基本上,运算符优先级。
Basically, operator precedence.
我相信
$return;
是一个语法错误。您不需要声明它 - perl 和 php 中的变量是无范围的。此外,
=
优先于?:
,因此您需要将()
添加到两个赋值中。I believe
$return;
is a syntax error. You don't need to declare it - variables in perl and php are scopeless.In addition
=
takes precedence over?:
so you need to add()
to both assignments.