我如何调用 grandparent 的构造函数(因为 parent 的构造函数未定义)?
How do I call the grandparent's constructor (because the parent's constructor is not defined)?
我相信,在 Perl 中调用 parent 的 class' 构造函数的规范方法是:
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($@);
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
函数?
However, this construct doesn't seem to work if Parent
does not explicitely define a new function (but Grandparent
does).
不正确。
$ 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
这是当您尝试从尚未声明的 class 继承时获得的警告。具体来说,您试图在未加载的情况下使用 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 不是 class,更不是 Net::FTP 的子 class。它没有方法,更不用说 new
方法了。从 Net::FTP::File.
继承是没有意义的
您似乎想要创建一个 Net::FTP 对象,因此替换
use parent 'Net::FTP::File';
和
use parent 'Net::FTP';
最后,您要为它添加到 Net::FTP 对象(包括继承自 Net::FTP 的 class 对象)的方法加载 Net::FTP::File。为此,只需添加
use Net::FTP::File qw( );
您似乎假设 Net::FTP::File
是 Net::FTP
的子class,因此
my $self = $class->SUPER::new('localhost') ...
应该调用 Net::FTP
的 new
方法。
然而,事实上,Net::FTP::File
并没有继承自Net::FTP
。相反,它重新定义了 Net::FTP
中的一些方法。因此,如果您的 class 继承自 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;
}
等等等等
我相信,在 Perl 中调用 parent 的 class' 构造函数的规范方法是:
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($@);
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
函数?
However, this construct doesn't seem to work if
Parent
does not explicitely define a new function (butGrandparent
does).
不正确。
$ 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
这是当您尝试从尚未声明的 class 继承时获得的警告。具体来说,您试图在未加载的情况下使用 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 不是 class,更不是 Net::FTP 的子 class。它没有方法,更不用说 new
方法了。从 Net::FTP::File.
您似乎想要创建一个 Net::FTP 对象,因此替换
use parent 'Net::FTP::File';
和
use parent 'Net::FTP';
最后,您要为它添加到 Net::FTP 对象(包括继承自 Net::FTP 的 class 对象)的方法加载 Net::FTP::File。为此,只需添加
use Net::FTP::File qw( );
您似乎假设 Net::FTP::File
是 Net::FTP
的子class,因此
my $self = $class->SUPER::new('localhost') ...
应该调用 Net::FTP
的 new
方法。
然而,事实上,Net::FTP::File
并没有继承自Net::FTP
。相反,它重新定义了 Net::FTP
中的一些方法。因此,如果您的 class 继承自 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;
}
等等等等