perl - 在继承函数中访问类变量?

标签 perl inheritance

我正在尝试在 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/

相关文章:

c++ - 派生结构与指向其他结构的结构

c++ - 重载虚函数并通过指向基类的指针调用派生函数

java - 在静态父方法中访问子类常量

perl - 如何使用 Moose 创建私有(private)/公共(public)变量和函数?

perl - Perl:如何将键/值对插入hashref并仍然保留引用

linux - merge - 以特定顺序追加二进制文件的内容

c++ - 如何创建一个不能被其他类继承的类?

java - 初始化抽象类的一般变体

perl - 自定义perl安装找不到Git.pm

perl - 在 perl 中写入文件