【发布时间】:2015-09-17 12:11:38
【问题描述】:
除了经典的函数调用
sub foo { ... };
foo 1, 2, 3;
Perl 允许定义闭包
my $foo = sub { ... };
$foo->(1, 2, 3);
(在这种情况下,词法本地)
即使我找不到它的非黑客用途,Perl 也允许这样做:
*main::foo = sub { ... }
这获得了与第一种形式几乎相同的效果,除了我必须在参数周围加上括号:
foo(1, 2, 3);
如果我不放括号,我会收到以下错误:
Number found where operator expected at - line 6, near "&main::foo 1"
(Missing operator before 1?)
syntax error at - line 6, near "main::foo 1"
Execution of - aborted due to compilation errors.
...如果我使用 &foo 1, 2, 3 语法调用它也会发生这种情况,明确表示它是关于一个函数的。
所以我的问题是:
为什么第一种形式可以省略括号,而第三种形式却不能?
第三种形式有目的吗?在我看来,在包的命名空间中注入回调是一种不好的做法,因为它会使事情变得隐含且不可检测。
感谢您的任何回答。
【问题讨论】:
-
也许 perl 必须首先查看函数定义,而
*main::foo = sub { ... }不会这样做。同样eval.in/434959也不起作用。 -
第三种形式在测试代码时有时很有用——它可以用来存根或替代昂贵的调用。
Test::MockModule基本上就是这样做的。有更好的方法(例如依赖注入),但有时您无法控制代码。
标签: perl