2016-07-31 77 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感谢您付出的努力来回答我的问题。经过一天太久,我一定犯了一个马虎的错误,虽然我确定我复制/粘贴了正确的错误信息。无论如何,我下次会做得更好。 –

相关问题