2016-07-31 135 views
2

我認爲,規範的方法來調用父類的構造函數中Perl是:如何調用祖父母的構造函數(因爲父母的構造函數沒有定義)?

package Child; 
our @ISA = 'Parent'; 

sub new { 
    my $class = shift; 
    my @args = @_; 
    my $self = $class->SUPER::new(@args); 
    return $self; 
} 

然而,這種結構似乎並沒有工作,如果Parent沒有明確地定義一個new功能(但Grandparent一樣) 。

這種情況,例如,Net::FTP::File

tq84_ftp.pm

package tq84_ftp; 

use warnings; 
use strict; 

our @ISA = qw(Net::FTP::File); 

sub new { 
    my $class = shift; 
    my $self = $class->SUPER::new('localhost') 
    or die([email protected]); 
    return $self; 
}  

1; 

script.pl

use tq84_ftp; 
tq84_ftp->new(); 

輸出:

Can't locate package Net::FTP::File for @tq84_ftp::ISA at tq84_ftp.pm line 10. 
Can't locate package Net::FTP::File for @tq84_ftp::ISA at tq84_ftp.pm line 10. 
Can't locate object method "new" via package "tq84_ftp" at tq84_ftp.pm line 10. 

如何指定我想要Perl找到正確的(這裏:grantparent的)new功能?

+1

你真的不應該問這個。當然,這是可能的,因爲大多數事情都在Perl中。但是你的類結構的設計是錯誤的,你不應該編寫代碼來繞過它。 – Borodin

+0

你當然可以幫助我指出我應該改爲什麼。 –

+0

您需要關於您的班級結構的幫助,如果您真的不知道如何着手,則需要發佈您的所有相關代碼。很可能你需要僱傭一個承包商。如果只有一兩個班級,那麼如果你展示你所擁有的一切,我們可能會在這裏幫助你,但我認爲這不太可能。 – Borodin

回答

5

看來你認爲Net::FTP::FileNet::FTP一個子類,因此

my $self = $class->SUPER::new('localhost') ... 

應該調用Net::FTPnew方法。

然而,事實上,Net::FTP::File不從Net::FTP沒有繼承。相反,它重新定義了Net::FTP中的一些方法。因此,如果您的課程從Net::FTP::File繼承,則它不會是Net::FTP的孩子。

如果您查看source code for Net::FTP,您可以輕鬆看到這一點。需要注意的是,沒有use base 'Net::FTP'use parent 'Net::FTP'或低於our @ISA = qw(Net::FTP)

package Net::FTP::File; 

use strict; 
use warnings; 
use Net::FTP; 

# ... 

sub Net::FTP::pretty_dir { 
    shift; 
    my $newp = shift; 
    if (defined $newp) { 
     $pretty = $newp; 
     $DirProcHash{cols} = $cols{pretty} if $pretty; 
     $DirProcHash{cols} = $cols{utility} if !$pretty; 
    } 
    return $pretty; 
} 

# ... 

sub Net::FTP::isfile { 
    my $ftp = shift; 
    return 1 if $ftp->exists(@_) && !$ftp->isdir(@_); 
    0; 
} 

等等等等

6

然而,這種結構似乎並沒有工作,如果Parent沒有明確地定義一個新的功能(但Grandparent一樣)。

不正確。

$ perl -E' 
    package Grandparent { 
     sub new { CORE::say(__PACKAGE__) } 
    } 

    package Parent { 
     our @ISA = "Grandparent"; 
    } 

    package Child { 
     our @ISA = "Parent"; 
     sub new { my $class = shift; $class->SUPER::new(); } 
    } 

    Child->new(); 
' 
Grandparent 

Can't locate package Net::FTP::File

這當您試圖從尚未聲明一個類繼承獲得的警告。具體來說,您正嘗試使用Net :: FTP :: File而不加載它。

替換

our @ISA = 'Net::FTP::File'; 

use Net::FTP::File qw(); 
our @ISA = 'Net::FTP::File'; 

use parent 'Net::FTP::File'; 

Can't locate object method "new" via package "tq84_ftp"

此消息是有點不清楚,但這樣的事實:Net::FTP::File->new不存在的到期。 Net :: FTP :: File不是一個類,更不用說Net :: FTP的子類。它沒有辦法,更不用說new方法。從Net :: FTP :: File繼承是沒有意義的。

你似乎想創建一個網:: FTP對象,所以更換

use parent 'Net::FTP::File'; 

use parent 'Net::FTP'; 

最後,你要加載的Net :: FTP文件::它添加到Net :: FTP對象(包括從Net :: FTP繼承的類的對象)的方法。要做到這一點,只需添加

use Net::FTP::File qw(); 
+0

添加到我的答案。將來,請發佈您實際運行的代碼,並請提供該代碼的實際輸出。 – ikegami

+0

@ikegame感謝您付出的努力來回答我的問題。經過一天太久,我一定犯了一個馬虎的錯誤,雖然我確定我複製/粘貼了正確的錯誤信息。無論如何,我下次會做得更好。 –

相關問題