2010-02-13 62 views
6

AFAIK繼承通常設置這樣的:我應該在編譯時而不是運行時建立繼承嗎?如果是的話,爲什麼?在Perl

package Mule; 
our @ISA = ("Horse", "Donkey"); 

是否有任何例子,其中use base(或use parent)是更好的呢?

+5

「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

+2

'BEGIN {@ISA = ...};'也在編譯時發生。 – friedo 2010-02-13 14:36:01

+0

@FM感謝評論:-)我改述了這個問題 – 2010-02-13 14:37:29

回答

3

在編譯時建立繼承避免了特別難以調試的依賴關係循環,如下所示。

# 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->wibbleMother。如果代之以兒童use parent qw(Mother)其繼承將建立之前,它試圖加載任何其他。

我一直在私密的這種依賴循環,企業代碼往往比公共代碼更加交織。它很難調試,這就是爲什麼我建議總是在編譯時建立繼承。

+0

謝謝,這是一個有用的例子。 – FMc 2010-02-15 12:56:40

5
use base qw(Horse Donkey); 

這大致相當於:

BEGIN { 
    require Horse; 
    require Donkey; 
    push @ISA, qw(Horse Donkey); 
} 

這是整潔,如果你需要加載的模塊代碼,以及從他們身上繼承。順便說一句,有多重繼承的問題,但那是一個不同的問題:)

編輯:編譯時間v運行時的優點:

  • 你有編譯時檢查的安全性與使用基地意味着如果您的基本模塊不存在於文件系統上,您的腳本甚至不會啓動。
  • 如果要決定使用在運行時給定的模塊,那麼你就可以測試和模塊添加到您的父母:

    如果(EVAL {需要X}){ 推@ISA「 X'; }

+3

你可以使用use parent qw(基類)或者使用base qw(基類)。父母比基礎更可取,因爲它有更少的黑暗魔法,但它不像核心基地那樣。 – 2010-02-13 13:03:14

+0

我在Perl中生鏽得太多,無法瞭解'父'。 Thanks @Leon +1 – ziya 2010-02-13 15:32:28

+1

當父類位於同一個文件中時,「base」模塊將工作。請參閱http://search.cpan.org/perldoc?base。 – FMc 2010-02-13 17:16:44

1

關於編譯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 baseuse parent編譯指示。如果您不特別需要use base(字段)的任何功能,也不需要通過use parent提供較長的向後兼容性,我建議您使用更輕的use parent

相關問題