我正在编写一个基本程序,其核心逻辑分为几个项目特定的模块以保持清洁(保持子程序按照程序的逻辑组织)。
突然无法从其中一个模块的main
包中暴露一个选项,并且使用our
语句似乎没有效果。
为简洁起见,我将复制+粘贴我写的一个孤立的测试用例来检查这种行为:
#!/usr/bin/perl
use warnings;
use strict;
use File::Basename;
# The variable to be read by the module.
our $verbose = 1;
# Load Output.pm from directory
use lib dirname "$0";
use Output;
write_message "Hello, world\n";
package Output;
use warnings;
use strict;
use parent "Exporter";
our @EXPORT = qw(write_message);
# Should be imported?
our $verbose;
sub write_message {
print $_[0] unless !$verbose;
}
1;
预期结果: "Hello, world"
实际结果:死亡沉默
很有可能我在Perl中尝试实现的目标甚至不可能,因为这不是模块的预期用途(哎呀,我理解为什么这样做&& #39; d是这样的。)
我对Perl还很陌生,而且有些事情我正在努力解决这个问题。我看到有人建议使用our
声明符在包中公开变量,但我无法理解为什么它不起作用。
PS:如果有人知道在模块之间拆分应用程序特定逻辑的更好方法,我也会对某些指针表示赞赏。 :)但首先,我更愿意了解为什么our
变量不起作用。
答案 0 :(得分:4)
our
语句只创建一个包变量(而my
创建一个词法变量)。它与导出
最好的选择可能是在Output
包中声明变量,并在其他地方将其作为$Output::verbose
访问。喜欢这个
#!/usr/bin/perl
use strict;
use warnings;
use File::Basename;
use lib dirname $0;
use Output;
$Output::verbose = 1;
write_message "Hello, world\n";
package Output;
use strict;
use warnings;
use Exporter 5.57 'import';
our @EXPORT = qw/ write_message /;
our $verbose;
sub write_message {
print $_[0] if $verbose;
}
1;
请注意,我还从$0
左右删除了不正确的引号,自Exporter
的第5.57版以来,导入的可能性(并且更可取)&# 39; s import
子程序而不是子类化
答案 1 :(得分:3)
our
在当前包中声明包变量。 main.pl中的那个引用$main::verbose
; Output.pm中的那个引用$Output::verbose
。
您可以使用全名$main::verbose
从任何地方访问变量,但您无法真正“导出”它,因为导出是指模块用户可以访问符号。你正试图做相反的事情。