我在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或其他方式获得此效果的最佳方法是什么?对于任何希望继承的类数据类,似乎都是理想的行为。
答案 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
添加到 Bar
和 class_has Item ...
的克隆版本(注意 +
上的前导 Item
)。
{
package Bar;
use Moose;
use MooseX::ClassAttribute;
extends 'Foo';
class_has '+Item' => ();
}
我现在可以更改子类 Item
而不会影响超类 Item
。