Moose类属性,类似于Class :: Data :: Inheritable

时间:2012-03-05 05:34:34

标签: perl moose

我在Moose类中有一个class属性,但是我希望它在覆盖父值的子类方面像Class::Data::Inheritable一样工作。也就是说,子类继承父级的值,直到在子类上调用setter,此时值变为不同。 e.g。

#!/usr/bin/perl
use warnings;
use strict;

{
    package Foo;
    use Moose;
    use MooseX::ClassAttribute;
    class_has Item => ( is => 'rw' );
}

{
    package Bar;
    use Moose;
    extends 'Foo';
}

Foo->Item(4);

# This prints "4, 4" as expected
#
print join( ", ", Foo->Item(), Bar->Item() ) . "\n"; 

Bar->Item(5);

# Would like this to print "4, 5", but it prints "5, 5"
#
print join( ", ", Foo->Item(), Bar->Item() ) . "\n"; 

使用MooseX::ClassAttribute或其他方式获得此效果的最佳方法是什么?对于任何希望继承的类数据类,似乎都是理想的行为。

2 个答案:

答案 0 :(得分:0)

我知道你要求继承,但可能是角色会帮助你以不同的方式解决你的问题。

尝试一个简单的例子:

#!/usr/local/bin/perl

use strict;
use feature 'say';

{
    package Bomb;
    use Moose::Role;
    sub fuse    { say "Bomb explode" }
    sub explode { say "Bomb fuse"}
}

{
    package Spouse;
    use Moose::Role;
    sub fuse    { say "Spouse explode"}
    sub explode { say "Spouse fuse"}
}

{
    package PracticalJoke;
    use Moose;
    with 'Bomb'   => { excludes => 'explode' },
         'Spouse' => { excludes => 'fuse' };
}

my $joke = PracticalJoke->new();
$joke->fuse();
$joke->explode();

使用'排除',您可以准确控制应该发生的事情。

看看why roles are awsome 以及来自Ovid的关于inheritance versus roles的幻灯片。

答案 1 :(得分:0)

我遇到了同样的问题,在寻找解决方案时找到了这个页面。距原帖发布快十年了,但我现在已经找到了一个解决方案,它可能会对下一个人有所帮助。

解决方案是将 MooseX::ClassAttribute 添加到 Barclass_has Item ... 的克隆版本(注意 + 上的前导 Item)。

    {
        package Bar;
        use Moose;
        use MooseX::ClassAttribute;
        extends 'Foo';
        class_has '+Item' => ();
    }

我现在可以更改子类 Item 而不会影响超类 Item