2013-08-31 61 views
3

一個模塊是否有可能在Perl到一個新的名稱分配給一個模塊,我們的代碼中使用?給予備用名在Perl

我的目的是:我的一些客戶希望.xls文件(電子表格Excel中::)和其他的.xlsx(Excel中::作家:: XLSX)。由於這兩個模塊都共享其大部分API,因此我希望能夠在項目開始時將該選項設置在某個位置,然後將其忽略掉,這也使得將來可以輕鬆地對其進行更改。它也可能用於諸如鼠標/穆斯等變化。

回答

6

看來,所有你真正想要的是能夠調用類的方法(如new)在類名在運行時確定。這其實很簡單:

my $spreadsheet_class = 'Spreadsheet::Excel'; 
my $sheet = $spreadsheet_class->new; 

當你調用一個方法就包含字符串標量變量,Perl將它作爲對包名稱的類方法。沒有花哨的符號表需要黑客,並且它在use strict下工作得很好。

+0

這是相當真實的,我所做的只是在不同地方的模塊上調用'new'。我認爲'嚴格'也會抱怨這一點(就像它抱怨'軟件引用'),但它並沒有在實踐中,所以這是成功的。也讓我更容易控制這個名字的範圍。謝謝! – sundar

+0

有沒有這種情況下,這將不足以@艾蒙的解決方案將成爲必要? – sundar

+1

它只允許你調用類方法。如果你需要做一些像'$ Class :: config_var = 1;'那麼你需要使用@ amon的解決方案(或啓用符號引用)。 – cjm

5

可以別名類的包藏匿到一個新的名字:

use strict; use warnings; use feature 'say'; 

package Foo; 
sub new { bless [] => shift } 
sub hi { say "hi from Foo" } 

package main; 

# Alias the package to a new name: 
local *F:: = *Foo::; # it could make sense to drop the "local" 

# make an objects 
my $f = F->new; 

# say hi! 
say $f; 
$f->hi; 

輸出:

Foo=ARRAY(0x9fa877c) 
hi from Foo 

另一個解決方案是動態子類需要的數據包。

use strict; use warnings; use feature 'say'; 

package Foo; 
sub new { bless [] => shift } 
sub hi { say "hi from Foo" } 

package Whatever; 
# no contents 

package main; 

# let Whatever inherit from Foo: 
# note that I assign, instead of `push` or `unshift` to guarantee single inheritance 
@Whatever::ISA = 'Foo'; 

# make an objects 
my $w = Whatever->new; 

# say hi! 
say $w; 
$w->hi; 

輸出:

Whatever=ARRAY(0x9740758) 
hi from Foo 

這些解決方案都在運行時工作,是非常靈活的。第二種解決方案依靠較少的魔力,並且看起來更清潔。然而,有一個機會,一個模塊測試爲ref($obj) eq 'Foo',而不是正確blessed $obj and $obj->isa('Foo'),這可能會造成斷線。

+0

大回答,謝謝!作爲一個方面說明,我自己在幾個地方使用'ref($ obj)eq'Classname''形式,現在改變它們。 :) – sundar

+1

@sundar'blessed'當然是'Scalar :: Util :: blessed'(只要確保這一點很清楚)。如果你比較'ref'-equality,子類將不起作用。 '祝福'測試確保我們沒有得到任何*不能調用方法「isa」對未經引用的參考*錯誤。 – amon

+0

您剛剛重寫了['Package :: Alias'](http://search.cpan.org/perldoc?Package::Alias)! – mob