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

Posted

技术标签:

【中文标题】Moose 类属性类似于 Class::Data::Inheritable【英文标题】:Moose class attribute that acts like Class::Data::Inheritable 【发布时间】:2012-03-22 15:42:50 【问题描述】:

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

#!/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 或其他方式获得这种效果的最佳方法是什么?对于期望从中继承的任何带有类数据的类来说,这似乎是理想的行为。

【问题讨论】:

FWIW Class::Data::Inheritable 与 Moose 不冲突。 Schwern:这可能是真的,虽然 Moose 对象必须从 Moose::Object 继承,所以至少会涉及到多重继承,这让我很困扰。你也没有得到 MooseX::ClassAttribute 给你的任何 Moose 属性声明优点。 【参考方案1】:

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

用一个简单的例子试试:

#!/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 的幻灯片。

【讨论】:

您可能想在答案中总结这些链接;这样,如果这些链接消失了,您就不会冒被删除的风险。 好的。我从提到的链接中添加了示例。【参考方案2】:

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

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

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

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

【讨论】:

以上是关于Moose 类属性类似于 Class::Data::Inheritable的主要内容,如果未能解决你的问题,请参考以下文章

在 Perl/Moose 中,如何将修饰符应用于所有子类中的方法?

Perl:在 Moose 类中添加编写器拒绝属性访问

Perl Moose 属性句柄设置方法

使用Moose with Test :: Class - 构造函数的问题

条件 Moose::角色消费

为啥 Moose 代码这么慢?