perl函数调用中的括号

时间:2013-12-08 11:05:20

标签: perl

AFAIK,perl中的括号用于:

  • 在表达式中设置评估优先级
  • 制作清单

所以,

my $r = ($x+$y) * $z;
my(@l) = (1,2,3);

函数调用中括号的含义是什么?我没有找到任何,sub会得到一个简单的参数列表。

#!/usr/bin/env perl

use Modern::Perl;
use Data::Dumper;

sub xxx { say Dumper \@_ }

xxx( 1,  2, 3  );
xxx( 1, (2, 3) );
xxx  1, (2, 3)  ;
xxx  1,  2, 3;

正确?

要求,因为perl -MO=Deparse没有从函数调用中删除括号。

所以下一个短剧

use Moose;
has 'arg' => (is=>'rw', isa=>'Str');

返回

has('arg', ('is', 'rw', 'isa', 'Str'));

而不是简单的

has('arg', 'is', 'rw', 'isa', 'Str');

这有什么不同吗?

2 个答案:

答案 0 :(得分:3)

在你的例子中,“它们都是相同的”的例外情况将是这样的:

xxx (1,2), 3;

以下区别:

has('arg', ('is', 'rw', 'isa', 'Str'));
has('arg', 'is', 'rw', 'isa', 'Str');

是前者构建一个列表,然后构建第二个列表,将第一个列表推送到它上面。后者将所有内容构建为单个列表。您可以使用B :: Concise看到差异;他们编译成略有不同的操作树。前一个例子的运行速度会稍微慢一点,但它的差别不大。

use strict;
use warnings;
use Benchmark qw(cmpthese);

cmpthese(-5, {
  once   => q[  my @x = (foo => (bar => 1, baz => 2))  ],
  twice  => q[  my @x = (foo =>  bar => 1, baz => 2 )  ],
});

__END__
       Rate twice  once
twice 216835/s    --   -1%
once  218228/s    1%    --

答案 1 :(得分:1)

当没有通过去除方法去除parens时,这是因为它们可用于确定优先级。代码段has('arg', 'is', 'rw', 'isa', 'Str')has('arg', ('is', 'rw', 'isa', 'Str'))生成不同的操作码(尽管在这种情况下可以安全地删除差异)。

Parens不会创建列表。 Perl中的“列表”不是不同的数据结构。它们只是堆栈段的更易于理解的描述。如果有什么东西会创建一个列表,那么它就是列表上下文中的逗号运算符,。 (但它没有列表)。

如果您正在调用的子例程在解析时已知,则函数调用的parens是可选的,即语法为any_function(@args)known_function @args。已知函数也可以使用 prototypes 来更改参数的解析方式(无论是否使用了parens)。对于已知函数,解除的调用是否使用parens无关:两者都产生相同的操作码。