2017-10-19 79 views
1

創建一個Perl模塊另一個類中調用從一個類的方法呢? 例如getJobStatus存在於ElectricCommander中,我可以做類似下面的事情嗎?通過它使用它

use EC; 
$obj = EC->new("myserver"); 
$obj->getJobDetails("1234"); 
+0

這種聲音就像你想要繼承'ElectricCommander'。 – melpomene

+1

'package'行應該首先出現。如果'ElectricCommander'輸出任何符號,這會產生很大的差別。 – melpomene

回答

1

組成似乎適合在這裏:方法添加到EC派遣到其他類的方法。

例如

package EC; 

use strict; 
use warnings; 

use ElectricCommander; 

sub new { 
    ... 
    $self->{EC} = ElectricCommander->new($server); 
    ... 
} 

sub getJobDetails { 
    my ($self, @args) = @_; 
    $self->{EC}->getJobDetails(@args); 
} 

,並且可以調用

use EC; 
my $ec_obj = EC->new(...); 
$ec_obj->getJobDetails(...); 

您也可以實例ElectricCommanderclass data,而不是在new,這樣它的對象是構建一次,當ECuse d。這是一個設計選擇,無論您是想讓EC實例都擁有自己的ElectricCommander對象,根據需要構建,還是一個對象適合所有對象的需求。

如果EC是真正延長ElectricCommander –使用它的大多數方法,覆蓋一些更增添了–,那麼你可以把它從(子類)ElectricCommander繼承。

大多數時候,當你碰到一個需要在另一個使用一個類你想組成,上面勾畫,其中一類使用的另一個功能(有-關係)。繼承是適合的,當你在構建一個經過仔細思考的類的層次結構時,父類放置更一般的或抽象的行爲,而其子類主要專門化它(是 - 關係)。

1

只需添加以下到EC包:

sub getJobDetails { shift->{EC}->getJobDetails(@_) } 

如果您有什麼樣多種方法,您可以使用動態生成包裝。

BEGIN { 
    for my $method_name (qw(getJobDetails ...)) { 
     my $local_method = sub { shift->{EC}->$method_name(@_) }; 

     no strict qw(refs); 
     *$method_name = $local_method; 
    } 
} 

你甚至可以重定向不存在EC如下的方法所有呼叫:

use Carp qw(croak); 

sub AUTOLOAD { 
    my $method_name = our $AUTOLOAD; 
    $method_name =~ s/^.*:://s; 
    return if $method_name eq 'DESTROY'; 

    my $remote_method = $_[0]->can($method_name) 
     or croak(sprintf("Can't locate object method \"%s\" via package \"%s\"", $method_name, ref($_[0]))); 

    my $local_method = sub { shift->{EC}->$remote_method(@_) }; 

    no strict qw(refs); 
    *$method_name = $local_method; 
    goto &$method_name; 
} 
1

做出的ElectricCommander可用的EC實例的所有方法中最簡單的方法就是讓ECElectricCommander一個子類:

package EC; 
use strict; 
use warnings; 

use parent 'ElectricCommander'; 

sub new 
{ 
    my $class = shift; 
    my $self = $class->SUPER::new(@_); 
    $self->login("user", "password"); 
    return $self; 
} 

1; 

現在

use EC; 
my $obj = EC->new("myserver"); 
$obj->getJobDetails("1234"); 

應該只是工作(TM)。

+1

注意:這將封裝關係(「EC有ElectricCommander」)轉換爲繼承關係(「EC是EletricCommander」)。這可能也可能不合適。 – ikegami