【发布时间】:2018-11-11 12:35:02
【问题描述】:
当属性的内容通过引用而不是通过mutator设置其值时,Moose有什么方法可以触发回调?
让我们假设以下代码:
has _changed => ( is => 'rw' , isa=>'Bool' ) ;
has attribute => (
is=>'rw', isa=>'Maybe[HashRef]',
default => sub { { a => 1 , b => 2 } },
trigger => sub { shift->_changed(1) }
) ;
触发器按预期工作,通过 mutator 设置属性值:
$self->attribute({ a => 2 , b => 2 }) ; # OK
但是通过它的键直接设置一个值然后触发器不会触发(当然):
$self->attribute->{a} = 3 ; # KO
我放弃了创建(和比较)序列化属性内容摘要的想法,因为它可能是具有多个嵌套级别的非常巨大的 hashref,并且在每个属性访问时创建摘要会产生性能问题。
绑定的 hashref(作为属性值)可能是一种可能的解决方案? 任何想法或建议都非常感谢。
注意:包含的 hashref 的结构是未知的(我正在编写一个 ORM 类,因此该结构可能会因存储在 NOSQL db 端的文档而异)。
【问题讨论】:
-
如果您需要使用语法
$self->attribute->{a} = ???来更新哈希键,我认为绑定哈希是唯一(?)选项。但是,如果您可以将语法更改为$self->attribute( <args> ),其中<args>可以是哈希引用或标量,其中attribute现在是一种方法(不是属性),而旧的attribute被重命名为例如_attribute,您可以避免使用绑定哈希。现在attribute方法将检查其参数是标量还是散列引用,并相应地更新_attribute。 -
@Håkon 我绝对避免通过内部引用访问属性,但我正在开发一个将被其他人使用的类,我担心如何使其健壮,因为我很确定即使不是最佳实践,一些开发人员也会使用快捷方式:-(