2

简洁版本

是否可以从在代码块中声明为our使用非限定名称但在外部使用限定名称的模块访问变量?BEGIN特别是,这可以在明确命名模块文件中的包的情况下完成吗?

例子

demomod.pm_

use strict;
use warnings;    
package demomod;
our $foo;
BEGIN { $foo = 42; }
1;

并且demoscript.pl成为

#!/usr/bin/perl -Tw
use strict;
use warnings;
BEGIN { @INC = ('.', @INC); }
use demomod;
print $demomod::foo."\n";

在这种情况下,所有名称都同意,并且一切正常。有没有办法package demomod;demomod.pm代码中省略该行并仍然让它工作?

动机

我问的原因是因为我在最近升级Foswiki时遇到了这些问题。该软件有一个没有行的模块(编辑:似乎该行仅在我的本地副本中丢失,原因未知)。它声明初始化一个变量,就像我的例子一样。还有一个 CGI 脚本,称为which sets and then do后跟. 由于变量未初始化,最后一行对我来说总是失败:Foswiki.pm package package$engineview@INCuse Foswiki ();$Foswiki::engine->run()

Can't call method "run" on an undefined value at …/view

BEGIN模块的块中,$engine设置正确但$Foswiki::engine显然不是。所以看起来这里有两个变量,一个是合格的,一个是不合格的。

所有这些代码显然都适用于其他人,以前的版本也适用于我,也没有package一行. 因此,当我试图了解它是如何破坏的时,我也试图了解它以前是如何工作的,没有那条线。是否有某种机制可以使这项工作发挥作用?

4

1 回答 1

3

如果您的代码中没有package语句,那么任何包变量都将被声明到main包中。所以不,你不能做你描述的事情。

如果您查看Foswiki您链接的代码的第 2 行,您会看到它确实有一个 package 语句。

于 2013-01-07T10:33:36.413 回答