如何调用祖父母的构造函数(因为父元素的构造函数未定义)?

Ren*_*ger 2 oop perl constructor super

我相信,在Perl中调用父类的构造函数的规范方法是:

package Child;
our @ISA = 'Parent';

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

但是,如果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($@);
  return $self;
}    

1;
Run Code Online (Sandbox Code Playgroud)

script.pl:

use tq84_ftp;
tq84_ftp->new();
Run Code Online (Sandbox Code Playgroud)

输出:

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.
Run Code Online (Sandbox Code Playgroud)

如何指定我希望Perl找到正确的(这里:grantparent's)new函数?

ike*_*ami 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
Run Code Online (Sandbox Code Playgroud)

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

当您尝试从尚未声明的类继承时获得此警告.具体来说,您尝试使用Net :: FTP :: File而不加载它.

更换

our @ISA = 'Net::FTP::File';
Run Code Online (Sandbox Code Playgroud)

use Net::FTP::File qw( );
our @ISA = 'Net::FTP::File';
Run Code Online (Sandbox Code Playgroud)

或者

use parent 'Net::FTP::File';
Run Code Online (Sandbox Code Playgroud)

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

这条消息有点不清楚,但这是由于Net::FTP::File->new不存在的事实.Net :: FTP :: File不是一个类,更不是Net :: FTP的子类.它没有方法,更不用说new方法了.从Net :: FTP :: File继承是没有意义的.

您似乎想要创建Net :: FTP对象,因此请替换

use parent 'Net::FTP::File';
Run Code Online (Sandbox Code Playgroud)

use parent 'Net::FTP';
Run Code Online (Sandbox Code Playgroud)

最后,您要为Net :: FTP对象(包括从Net :: FTP继承的类的对象)添加的方法加载Net :: FTP :: File.要做到这一点,只需添加

use Net::FTP::File qw( );
Run Code Online (Sandbox Code Playgroud)


Sin*_*nür 5

看来你假设它Net::FTP::File是和的子类Net::FTP,因此

my $self = $class->SUPER::new('localhost') ...
Run Code Online (Sandbox Code Playgroud)

应该调用Net::FTPnew方法.

但是,实际上,Net::FTP::File 并不是继承自的Net::FTP.相反,它重新定义了一些方法Net::FTP.因此,如果你的类继承自Net::FTP::File,那么它就不会是孩子了Net::FTP.

如果你查看源代码,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;
}
Run Code Online (Sandbox Code Playgroud)

等等