2010-06-21 73 views
-1
package a::b::c:d 

my $res = a::b::c:e->new(); # i am doing like this 
# is there any othere to do this 

sub new { 
... 
my $self = { 
    #result = a::b::c:e->new(); 
    } 
} 

sub test { 
} 

sub test2 { 
} 


1; 

package a::b::c:e 

sub new { 
... 
} 

sub testresult { 
} 
1; 

我的問題是:如何處理這種情況在面向對象的perl

  • 如何initalize的e模塊中新d本身,而創造每一個函數和

  • 如何使用將一些結果存入e:testresult

+1

'a :: b :: c:e'不是一個有效的軟件包名稱,但是小寫的名稱不應該使用。 – Ether 2010-06-21 15:10:17

+0

爲測試目的很好..我猜。但是最佳派對是不對的 – Tree 2010-06-24 13:05:09

回答

2

有兩種策略 - 檢查符號表以初始化創建,或使用AUTOLOAD並使用can進行測試。

sub AUTOLOAD { 
    my $self = shift; 

    my $method = $AUTOLOAD; 
    $method =~ s/.*://; # strip package name 

    if ($self->{'result'}->can($method)) { 
     return $self->{'result'}->$method(@_); 
    } else { 
     croak "Unknown method : $method"; 
    } 
} 

但符號表訣竅是脆的,因爲如果他們正在使用繼承,你不會看到繼承:當你要處理的情況下該方法是不存在的AUTOLOAD可以梅西耶方法也沒有向上走@ISA。典型的 - (即使他們不是,他們可能會開始在未來,這將導致事情打破使用繼承)

...

,當你試圖複製另一個模塊的接口,你得趕緊繼承的情況下,所以你可能要問自己的關係是什麼::d::e之間:

  • a::b::c::da::b::c::e
  • a::b::c::d使用a::b::c::e

如果它是一個is-a關係,它通常更適合繼承(儘管你可能在每個方法周圍都有包裝,並且仍然需要通過整個練習)。如果它是一個使用關係,賠率是你不希望從他們每一個最後的方法繼承,並可以直接硬編碼的列表(儘管該列表可能,如果使用的一類更新更改)

foreach my $method (@list_of_methods_to_copy) { 
    *{$method} = sub { 
     my $self = shift; 
     return $self->{'results'}->$method(@_); 
    } 
} 
+0

我問這個?但是,任何謝謝:-) – Tree 2010-06-21 12:13:44

+0

我是這麼認爲的,而不是「創造每一個功能」。如果這不是你要求的,你能給出一些你想要做的具體事例嗎? (您希望如何與它進行交互等) – Joe 2010-06-21 14:17:46

0

假如你不想在兩個類之間尋找繼承,它在我看來你可能想用Class::Delegator來組成你的類。這樣,您可以通過在a::b::c::d中輸入以下內容來創建委派例程。

use Class::Delegator send => 'testresult', to => '{result}'; 

但你總有需要修正你的構造:

my $self 
    = bless { 
     result => a::b::c::e->new() 
    }, $class_name 
    ; 
return $self; 

已經這樣做了,你就會有一個字段「{}結果」委託給。

相關問題