我试图在我们的代码库中创建一个自定义模块的子类。我们将模块放在我们所有文件中包含的目录中。所以我们从
开始NSLog(@"layoutSubviews: mediaItem=%p image=%p size=%@",
self.mediaItem, self.mediaItem.image,
NSStringFromCGSize(self.mediaItem.image.size));
接下来,我的父模块位于use Env;
use lib "$ENV{OurKey}/RootLib"; # All of our modules are here
,其代码长期存在,所以我宁愿不改变其中任何一个,而是让孩子能够继承它原样。
RootLib/Dir1/Parent.pm
此时,我有点迷失,因为我已经看到了许多不同的方法来定义子构造函数,但没有一个对我有用。这就是我所拥有的,但它不起作用,因为在子包中找不到应该从父项继承的子程序。子包位于package Parent;
use strict;
use warnings;
use Env;
use lib "$ENV{OurKey}/RootLib";
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = {};
# Some other stuff
bless ($self, $class);
return $self;
}
RootLib/Dir1/Dir2/Child.pm
然后,在我的test.pl文件中,我有
package Child;
use strict;
use warnings;
use vars qw(@ISA);
use Env;
use lib "$ENV{OurKey}/RootLib";
require Dir1::Parent;
push @ISA, 'Dir1::Parent';
sub new {
# This constructor is clearly incorrect, please help
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = Parent::new($class);
bless ($self, $class);
return $self;
}
答案 0 :(得分:2)
父类声明它在package Parent
中(即使包含它的文件是Dir1/Parent.pm
),因此孩子的@ISA
应该只包括Parent
}。
或者您可以通过一些额外的use lib ...
语句解决您不幸的目录结构。
package Child;
use lib "$ENV{OurKey}/RootLib/Dir1";
require Parent; # found in $OurKey/RootLib/Dir1/Parent.pm
our @ISA = ('Parent');
...
# test.pl
use lib "$ENV{OurKey}/RootLib/Dir1/Dir2";
use Child; # found in $OurKey/RootLib/Dir1/Dir2/Child.pm
...
答案 1 :(得分:0)
准父类有package Parent;
,但您有@ISA = 'Dir1::Parent';
。那些不匹配,这就是无法找到方法的原因。 (那,以及你实际上没有在任何地方定义方法的事实!)
文件名,package
语句中的名称,use
语句中的名称以及@ISA
中的名称都必须匹配。
以下是两种可能的解决方案。
Dir1::Parent
和Dir1::Dir2::Child
use lib "$ENV{OurKey}/RootLib";
use Dir1::Parent qw( );
use Dir1::Dir2::Child qw( );
(请注意use Env
已删除,因为它未被使用。)
(.../RootLib/)Dir1/Parent.pm
:
package Dir1::Parent; # Must match the file name.
use strict;
use warnings;
...
(.../RootLib/)Dir1/Dir2/Child.pm
:
package Dir1::Dir2::Child; # Must match the file name.
use strict;
use warnings;
use Dir1::Parent qw( ); # Must match the file name
our @ISA = 'Dir1::Parent'; # and the package name.
-or-
use parent 'Dir1::Parent'; # This can replace the other two lines.
...
Parent
和Child
不要在模块中修改@INC(例如通过use lib
)。您的脚本应包含以下内容:
use lib
"$ENV{OurKey}/RootLib/Dir1",
"$ENV{OurKey}/RootLib/Dir1/Dir2";
use Parent qw( );
use Child qw( );
(注意,在另一个库目录中有一个库目录真的很奇怪!)
(.../RootLib/Dir1/)Parent.pm
:
package Parent; # Must match the file name.
use strict;
use warnings;
...
(.../RootLib/Dir1/Dir2/)Child.pm
:
package Child; # Must match the file name.
use strict;
use warnings;
use Parent qw( ); # Must match the file name
our @ISA = 'Parent'; # and the package name.
-or-
use parent 'Parent'; # This can replace the other two lines.
...
至于构造函数,
父:
sub new {
my $class = shift; # That proto thing is a bad practice.
my $self = bless({}, $class); # Don't need two lines to do this.
# ...
return $self;
}
子:
sub new {
my $class = shift; # That proto thing is a bad practice.
my $self = $class::SUPER->new(); # Don't need two lines to do this.
# If you don't need to do anything here,
# ... # you can just inherit the parent's new
# by removing this sub entirely.
return $self;
}