perl "do" 工作"require"不工作:未定义的子例程



由于我一直在从别人所说的"perl4编码风格"重构我的一些代码,以使用packages,我有一个问题,我仍然不完全理解。我知道use在编译时包含一个文件,在运行时包含require(以及其他差异),两者都像在BEGIN部分中一样运行。我知道do有点像eval(有一些不同)。

我有一个可以单独运行的脚本(B),我从另一个脚本(C)中调用它作为requireScript B在.pm文件(a)上调用一个require,该文件只有两个子(一个用于设置变量,另一个用于返回变量)和一个声明为our的变量(我猜my在这里也会实现同样的效果)。这个.pm不是用package封装的(因此是这种情况)。如果我运行脚本B,它可以顺利运行。如果我从脚本C(它也有一个require用于package'd.pm,即requires a.pm,并使用访问函数)中选择require剧本B,我得到:

Undefined subroutine &main::func_in_A called at script_B

但是,如果script_B中的I doA.pm,则一切正常。

当我输入这个问题时,我想我意识到发生了什么,但无论如何让我问一下,只是为了确定一下。

这是因为require会跟踪它加载的文件(而do不会),因此它只加载一次文件,尽管那一次在包的命名空间中,因此在那里执行require时,符号不会进入MAIN吗?如果没有,那么我在这里错过了什么?

是的,我认为你的诊断是正确的。由于A.pm缺少package语句,因此它中的子语句将在评估文件时处于活动状态的任何包下定义。由于do没有防止双重评估的保护,A的潜艇分为两个不同的包。由于require是这样做的,所以它们最终在一个包中,而哪个包取决于谁先加载A。

解决方案:不要在没有package语句的文件上使用require(当然也不要使用use):)

最新更新