如何在Perl 5中使用括号?

时间:2011-07-14 18:18:42

标签: perl

这是一个Devel :: REPL会话(我的Perl版本是v5.10.1)。你能解释一下结果吗?

0:main$ my $x = 1,2,4
[
  1,
  2,
  4
]

0:main$ my $y = (1,2,4)
Useless use of a constant in void context at (eval 296) line 8.
4

我刚刚开始学习Perl,但仍然遇到了困扰上下文的麻烦。无论如何,我认为我理解为什么第二次任务会做它的作用。那是因为我们有一个标量上下文,这就是为什么根本没有构造列表的原因,我们只是重复执行逗号运算符,而那个opetator只返回它的右操作数。正确?

但是,第一次作业有什么问题?它不应该等同于第二个吗?在某些时候,我认为括号不提供任何神奇的语义来构建列表 - 它们只是将元素组合在一起,如果元素最终在列表上下文中使用,它们只是转换为列表。显然,那不是真的。

好吧,好吧。那么括号的特殊作用是什么?

2 个答案:

答案 0 :(得分:6)

Devel::REPL正在评估列表上下文中的每个输入行,然后打印结果列表。所以有效的第一行就是:

 say join ', ' => do {my $x = 1, 2, 4}

解析为:

 say join ', ' => do {(my $x = 1), (2), (4)}

所以REPL打印“1,2,4”,因为它从do块接收了3个值。

第二行是:

 say join ', ' => do {my $x = (1, 2, 4)}

解析为:

 say join ', ' => do {(my $x = scalar(1, 2, 4))}

标量上下文中的列表返回其最后一个元素,该元素分配给$x,然后由do块返回,随后打印“4”。

答案 1 :(得分:5)

我认为第一个语句的行为是Devel::REPL的结果,但我现在还没有它可以用来测试这个假设。

Perl中的括号主要调整优先级。他们还可以调整解析器查看某些语句的方式,但这不是这种情况。 =的优先级高于,,因此在第一个语句中,如果Devel::REPL评估列表上下文中的语句,则将其解析为第一个元素是赋值结果的列表1到$x,第二个和第三个值是2和4.在第二个优先级已经改变,结果上下文已经改变,因此,在标量上下文中,4分配给$x

$ perl -MO=Deparse,-p -e 'my $x = 1,2,4'
((my $x = 1), '???', '???');
-e syntax OK

$ perl -MO=Deparse,-p -e 'my $x = (1,2,4)'
(my $x = ('???', '???', 4));
-e syntax OK

我敢打赌,如果您在scalar(my $x = 1,2,4)中投放Devel::REPL,则结果为4,$x等于1。