这有效:
use strict;
X("xxxxxx");
sub X { print shift;}
这会产生错误:
use strict;
BEGIN {
X("xxxxxx");
}
sub X { print shift;}
错误:
Undefined subroutine &main::X called at ./test.pl line 5.
这是有道理的,因为我们在执行sub ...时处于编译阶段的中间,所以编译器还没有进入子声明/定义。
...但是:添加转发声明(在BEGIN阻止之前或其中)并没有帮助:
use strict;
sub X;
BEGIN {
X("xxxxxx");
}
sub X { print shift;}
为什么在BEGIN块中调用函数时前向声明不起作用?我认为它发生在编译阶段,my
声明的方式。
perldoc perlsub
似乎没有任何消息。
答案 0 :(得分:8)
BEGIN
块在解析后立即执行 。这意味着perl已经看到了sub 1 的定义。您唯一的解决方案是在使用之前定义功能:
sub foo { print shift }
# When the parser reaches this point, the "foo" sub has been compiled
BEGIN {
# Ergo, "foo" can be used here
foo("xxx");
}
# The BEGIN block is executed once the parser arrives here
您还可以选择稍后执行的移相器,例如INIT
:
INIT {
foo("xxx");
}
sub foo { print shift }
BEGIN
和朋友记录在perldoc perlmod
sub foo;
这样的预先声明仅在原型的上下文中为解析器提供指导,而裸字与子例程调用消歧。它不会使解析器跳转到实际定义。由预先声明生成的子例程存根实际上不可调用。