假设我有以下简单模块,其中有一个
new
方法和一个 say
方法。
package foo;
use strict;
use warnings;
sub new {
my $class = shift;
my $self = {};
bless $self, $class;
return $self;
}
sub say {
my $self = shift;
print join( ", ", @_ ) . "\n";
}
如果我想调用这个方法,我可以这样做:
my $foo = foo->new();
$foo->say("foo", "bar");
是否可以在没有括号的情况下调用此方法,就像独立函数一样?
当我尝试这样做时,我收到此错误:
my $foo = foo->new();
$foo->say "foo", "bar";
# String found where operator expected at HelloWorld.pl line 8, near "->say "foo""
# (Missing operator before "foo"?)
# syntax error at HelloWorld.pl line 8, near "->say "foo""
# BEGIN not safe after errors--compilation aborted at HelloWorld.pl line 14.
据我目前的理解,这与 Perl 编译器能够提前理解哪些符号是顶级函数有关。当使用独立函数时,Perl 有足够的信息来理解这是一个函数调用,而对于受祝福的哈希上的方法,Perl 无法弄清楚,并选择将其视为标量上下文。
有什么办法可以让这种行为成为可能吗?
我这样做的主要动机是创建一个类似包装器的结构来进行度量计时。例如
my $result = $timer->run $metric_name, sub {
call_some_expensive_method($some_vars);
};
如果我使用括号,我会开始与我的perltidy设置进行斗争,并得到如下结果,我发现这些结果的可读性要差得多。
my $result = $timer->run(
$metric_name,
sub {
call_some_expensive_method($some_vars);
});
我一直在尝试的另一个选项是创建一个包装行为的顶级函数,允许 Perl 编译器正确理解上下文。
sub timed {
return shift->run(@_);
}
...
my $result = timed $timer, $metric_name, sub {
call_some_expensive_method($some_vars);
};
如果调用没有参数,则只能在方法调用上使用括号。
$foo->say "foo", "bar"
意味着
$foo->say() "foo", "bar"
这解释了为什么 Perl 在遇到
"foo"
时抱怨缺少运算符。