AFAIK繼承通常設置這樣的:我應該在編譯時而不是運行時建立繼承嗎?如果是的話,爲什麼?在Perl
package Mule;
our @ISA = ("Horse", "Donkey");
是否有任何例子,其中use base
(或use parent
)是更好的呢?
AFAIK繼承通常設置這樣的:我應該在編譯時而不是運行時建立繼承嗎?如果是的話,爲什麼?在Perl
package Mule;
our @ISA = ("Horse", "Donkey");
是否有任何例子,其中use base
(或use parent
)是更好的呢?
在編譯時建立繼承避免了特別難以調試的依賴關係循環,如下所示。
# Child.pm
package Child;
our @ISA = qw(Mother);
use Foo;
# Mother.pm
package Mother;
sub wibble { 42 }
# Foo.pm
package Foo;
use Child;
Child->wibble;
如果你之前「使用童工」「使用富」,那麼富將嘗試建立它繼承了之前調用Child->wibble
上Mother
。如果代之以兒童use parent qw(Mother)
其繼承將建立之前,它試圖加載任何其他。
我一直在私密的這種依賴循環,企業代碼往往比公共代碼更加交織。它很難調試,這就是爲什麼我建議總是在編譯時建立繼承。
謝謝,這是一個有用的例子。 – FMc 2010-02-15 12:56:40
use base qw(Horse Donkey);
這大致相當於:
BEGIN {
require Horse;
require Donkey;
push @ISA, qw(Horse Donkey);
}
這是整潔,如果你需要加載的模塊代碼,以及從他們身上繼承。順便說一句,有多重繼承的問題,但那是一個不同的問題:)
編輯:編譯時間v運行時的優點:
如果要決定使用在運行時給定的模塊,那麼你就可以測試和模塊添加到您的父母:
如果(EVAL {需要X}){ 推@ISA「 X'; }
關於編譯VS-運行時:
在Perl中,模塊(包/命名空間)通常生活在單獨的文件中。即可以在Some/Module.pm中找到Some::Module
。在這種設置中,編譯與運行時差異不會有太大影響。通過use()
加載的模塊的運行時間將在調用代碼的編譯時間繼續之前進行。觀察報:
文件Some/Module.pm
:
package Some::Module;
BEGIN{ print "Some::Module - compile time\n" }
print "Some::Module - run time\n";
1;
文件test.pl
:
BEGIN{ print "Just started compiling the program.\n" }
use Some::Module;
BEGIN{ print "main - compile time\n" }
print "main - run time\n";
輸出將是:
Just started compiling the program.
Some::Module - compile time
Some::Module - run time
main - compile time
main - run time
因此,our @ISA = qw(Base);
將彙編之前執行的主程序在加載t後繼續他模塊。
但是,分配給@ISA
不能確保已加載基類是正確的。這就是爲什麼我們有use base
和use parent
編譯指示。如果您不特別需要use base
(字段)的任何功能,也不需要通過use parent
提供較長的向後兼容性,我建議您使用更輕的use parent
。
「base」和「parent」模塊允許您在編譯時建立ISA關係。相反,在運行時自己修改'@ ISA'。有鑑於此,改變你的問題的一種方法是這樣的:先建立繼承(編譯時)而不是後來建立繼承通常是有利的,爲什麼?另請參閱以下相關問題:http://stackoverflow.com/questions/1378309/whats-the-difference-between-use-base-and-isa-in-perl/1379276和http://stackoverflow.com/questions/ 876471 /什麼-是最差母 - 基中-perl的-5間。 – FMc 2010-02-13 14:27:45
'BEGIN {@ISA = ...};'也在編譯時發生。 – friedo 2010-02-13 14:36:01
@FM感謝評論:-)我改述了這個問題 – 2010-02-13 14:37:29