我不明白这里发生了什么:这些Perl使用行会发生什么?
use PAR { file => 'foo.par', fallback => 1 };
我认为这是一个匿名的哈希值。 use
系列模块如何使用它?你能说出一些光明吗?
编辑:我对PAR模块不感兴趣。我只是对如何在幕后工作感兴趣。我该如何配置我的模块?
我不明白这里发生了什么:这些Perl使用行会发生什么?
use PAR { file => 'foo.par', fallback => 1 };
我认为这是一个匿名的哈希值。 use
系列模块如何使用它?你能说出一些光明吗?
编辑:我对PAR模块不感兴趣。我只是对如何在幕后工作感兴趣。我该如何配置我的模块?
更基本,这是有趣的hashref语法做什么(使用perldoc -f use作为参考):
说我们有这个基本模块(把它放在Foo.pm
在当前目录):
package Foo;
use Data::Dumper;
sub import
{
print "import was passed these arguments: ". Dumper(\@_);
}
1;
当我们拨打
perl -I. -wle'use Foo { a => 1, b => 2}'
时,
,代码Foo->import({a=>1, b=>2})
被执行。因此,这是我们得到的输出:
import was passed these arguments: $VAR1 = [
'Foo',
{
'a' => 1,
'b' => 2
}
];
基本上,这句法让我们做的魔法与Exporter,但实际上你可以让import()
做任何你喜欢的(只是一定要记录巨资,以不导致混淆!)
PAR是CPAN模块Perl Archive Toolkit。 hashref是传递给PAR的配置参数。
代码:
use PAR { file => 'foo.par, fallback => 1 };
use Foo::Bar;
意味着使用Foo::Bar
如果可用,否则退回到使用存档“foo.par
”(这大概持有Foo::Bar
存档版本)。
当你模块use
,你可以传递一个参数列表给它。在你的例子中(似乎有一个错字,缺少一个结尾引用),一个包含一个元素(一个散列引用)的列表被传递。
更一般地:
use Module LIST
变为这样的:
BEGIN {
require Module;
Module->import(LIST);
}
的BEGIN
块确保所有的事情发生在编译时。 require
将模块加载到内存中,如果它尚未存在。然后在原始use
语句中调用模块的import()
方法,并传递任何参数(如LIST
)。
为了让您自己的模块能够处理这样的参数,您的模块需要定义一个import()
方法。许多模块不这样做;相反,他们从Exporter
类继承import()
。有关更多详情,请参阅perldoc -f use。
如果你的模块定义了自己的import()
方法,你要么需要符号导出到客户端代码自己,或者更常见的是,使用由Exporter
提供的export_to_level()
方法。此方法的第一个参数是一个正整数,用于指定要将符号导出到的调用堆栈中的级别。最常见的值1意味着将一个级别的符号导出以上当前包 - 也就是说,使用您的模块的客户端代码。这里是你的import()
方法需要做的概述。
sub import {
my ($class, @args) = @_;
# Do whatever you need to do with the LIST of arguments
# supplied by the client code using your module.
# Let Exporter do its normal work of exporting symbols
# into the client code using your module.
$class->export_to_level(1, @_);
}
是的,这是一个匿名散列。它作为参数传递给模块import
方法。
直接回答你的问题:PAR确实this (line 340):
# called on "use PAR"
sub import {
my $class = shift;
[...]
my @args = @_;
[...]
# process args to use PAR 'foo.par', { opts }, ...;
foreach my $par (@args) {
if (ref($par) eq 'HASH') { # <---- This is what handle's your case!
# we have been passed a hash reference
_import_hash_ref($par);
}
elsif ($par =~ /[?*{}\[\]]/) {
# implement globbing for PAR archives
[...]
}
else {
# ordinary string argument => file
[...]
}
}
现在,不幸的是,一旦你深入到什么是真正发生的事情,你就会意识到你选择了最复杂的一个模块上CPAN作为一个学习的例子,所以我建议你看看fine documentation on modules instead。为你提供一个指导,寻找什么:当你“使用”一个模块并为use语句提供参数时,perl将加载模块并用参数列表调用它的“import”方法。
在你的例子中,只有一个参数:对散列的引用。 {key =>“value”,key2 =>“value2”,...}语法是匿名哈希的构造函数。这些记录在the perlref manual page中,但在the perlreftut tutorial中以更友好的术语解释。
哦。抱歉。我不明白是什么让语法起作用。我对PAR模块本身并不感兴趣,只是作者如何做到这一点。 – Geo 2009-09-04 21:25:31
阿哈!在那种情况下,我刚刚提供了你的问题的真实答案。 :) – Ether 2009-09-04 21:43:59