我正在尝试在 Perl 中创建从单个父类继承类函数的子类。我让它部分工作,使用对象方法语法 Child->inheritedMethod()
调用子对象外部的继承函数,并且 my $class=shift; $class->inheritedMethod();
在子类中,如 here 所述.
但是,对于继承的方法,似乎控制权被传递给了父类,并且该方法使用父变量在父范围内运行。例如,这是在父类中:
our $VERSION = 0.11;
our $NICKNAME = "Parent Base";
sub version{ $VERSION }
sub whoami{ $NICKNAME }
sub whereami{
my $class = shift;
print "should be printing whereami right now...\n";
print "## In ",(caller(1))[3]," of ",$class->whoami," ",$class->version," in ",__PACKAGE__,"\n";
}
每个子类都声明了自己的 $VERSION
和 $NICKNAME
,我希望可以访问它们来代替父变量。但是当我从 child 那里调用 whereami
时,它给出了
## Child::Parent Base 0.11 in Parent 的方法
.
问题:
有办法解决这个问题吗?我应该使用其他一些模块,例如 Moo(se)?导出所有方法而不是继承,我听说不应该这样做(污染命名空间,这里不是问题)?
这仍然是使用对象和对象的问题吗 属性/变量?由于我的团队的原因,我试图避免它 厌恶面向对象。
- 继承通常是这样工作的, 或者只是 Perl?我以为该方法会在范围内调用 子类的,不传递给父类。
最佳答案
问题在于该方法从声明变量的词法范围(即父类)访问变量。因此,类变量与类属性不同。
您可以通过完全限定其名称来访问正确的变量(在 strict refs
下不可能:
#!/usr/bin/perl
use warnings;
use strict;
{ package Parent;
our $package = 'Parent';
sub get_package {
my $class = shift;
{ no strict 'refs';
return (caller(0))[3], $class, ${"$class\::package"}
}
}
}
{ package Son;
use parent 'Parent';
our $package = 'Son';
}
print join ' ', 'Son'->get_package, "\n";
print join ' ', 'Parent'->get_package, "\n";
在 Moo* 中,您可以使用 Moo*X::ClassAttribute
:
#!/usr/bin/perl
use warnings;
use strict;
{ package Parent;
use Moo;
use MooX::ClassAttribute;
class_has package => (is => 'ro',
default => 'Parent');
sub get_package {
my $class = shift;
return $class->package;
}
}
{ package Son;
use Moo;
use MooX::ClassAttribute;
extends 'Parent';
class_has package => (is => 'ro',
default => 'Son');
}
print 'Parent'->get_package, "\n";
print 'Son'->get_package, "\n";
注意 MooX::ClassAttribute 说
Overriding class attributes and their accessors in subclasses is not yet supported.
与 Moose 不同,您不能使用 class_has '+package' => (default => 'Son');
语法进行覆盖。
关于perl - 在继承函数中访问类变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22991557/