将运行时需要的数据文件与Perl模块捆绑在一起的“正确”方式是什么,以便模块在使用前可以读取其内容?如何使用Perl模块包含数据文件?
一个简单的例子就是这个Dictionary模块,它需要在启动时读取(字,定义)对列表。
package Reference::Dictionary;
# TODO: This is the Dictionary, which needs to be populated from
# data-file BEFORE calling Lookup!
our %Dictionary;
sub new {
my $class = shift;
return bless {}, $class;
}
sub Lookup {
my ($self,$word) = @_;
return $Dictionary{$word};
}
1;
和驱动程序,Main.pl:
use Reference::Dictionary;
my $dictionary = new Reference::Dictionary;
print $dictionary->Lookup("aardvark");
现在,我的目录结构是这样的:
root/
Main.pl
Reference/
Dictionary.pm
Dictionary.txt
我似乎无法得到Dictionary.pm到在启动时加载Dictionary.txt。我已经尝试了一些方法来得到这个工作,如...
使用BEGIN块:
BEGIN { open(FP, '<', 'Dictionary.txt') or die "Can't open: $!\n"; while (<FP>) { chomp; my ($word, $def) = split(/,/); $Dictionary{$word} = $def; } close(FP); }
没有骰子:Perl是在寻找CWD的Dictionary.txt,这是主脚本(“Main.pl”)的路径,而不是模块的路径,所以这会给出File Not Found。
使用DATA:
BEGIN { while (<DATA>) { chomp; my ($word, $def) = split(/,/); $Dictionary{$word} = $def; } close(DATA); }
,并在模块
__DATA__ aardvark,an animal which is definitely not an anteater abacus,an oldschool calculator ...
,因为在编译时BEGIN执行这也失败了,年底前DATA可用。
硬编码的模块
our %Dictionary = ( aardvark => 'an animal which is definitely not an anteater', abacus => 'an oldschool calculator' ... );
卷中的数据,但是断然非维护。
类似的问题在这里:How should I distribute data files with Perl modules?而是一个涉及通过CPAN安装的模块,而不是相对于当前脚本模块,我试图做的。
请注意,原型(即'sub new()')对方法有*无效。它们不是函数签名,[它们是完全不同的](https://stackoverflow.com/questions/297034/why-are-perl-5s-function-prototypes-bad)。除非你知道你在做什么,否则不要使用它们。如果您想要函数签名,请考虑[Method :: Signatures](https://metacpan.org/pod/Method:Signatures),[Kavorka](https://metacpan.org/pod/Kavorka)或[Function ::参数](https://metacpan.org/pod/Function::Parameters)。 – Schwern
我建议在'INIT'而不是'BEGIN'中使用'DATA'来确保数据在运行时间之前被初始化。它也使它更自我记录 – Borodin
@Schwern最近哎呀我的坏,太多的C/C++!我将编辑删除这些。 –