我不明白這裏發生了什麼:這些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