我正在为驼鹿对象编写一个模块。我想允许使用此对象的用户(或我自己......)根据他/她的需要动态添加一些字段。我无法先验地定义这些字段,因为我根本不知道它们是什么。
我目前只是添加了一个名为 extra 的 hashref 类型字段,该字段设置为 rw,因此用户可以简单地将内容放入该哈希中:
# $obj is a ref to my Moose object
$obj->extra()->{new_thingie}="abc123"; # adds some arbitrary stuff to the object
say $obj->extra()->{new_thingie};
这有效。但是……这是常见做法吗?还有其他(可能更优雅的)想法吗?
请注意,我不想创建另一个模块来扩展这个模块,这实际上只是为了我想添加的即时内容。
I'm writing a module for a moose object. I would like to allow a user using this object (or myself...) add some fields on the fly as he/she desires. I can't define these fields a priori since I simply don't know what they will be.
I currently simply added a single field called extra of type hashref which is is set to rw
, so users can simply put stuff in that hash:
# $obj is a ref to my Moose object
$obj->extra()->{new_thingie}="abc123"; # adds some arbitrary stuff to the object
say $obj->extra()->{new_thingie};
This works. But... is this a common practice? Any other (possibly more elegant) ideas?
Note I do not wish to create another module the extends this one, this really just for on-the-fly stuff I'd like to add.
发布评论
评论(4)
我可能会通过本机特征来做到这一点:
在一个对象上,您可以像下面这样使用它:
此类内容的常见用例是将可选的可自省数据添加到异常和消息类。
I would probably do this via native traits:
On an object you'd use this like the following:
A common use-case for stuff like this is adding optional introspectable data to exception and message classes.
如果您还没有使类不可变(有一个 性能损失(除了我担心动态更改类定义之外),您应该能够通过获取对象的元类来做到这一点(使用
$meta = $object ->meta
) 并使用 add_attribute 方法="noreferrer">类::MOP::类。输出:
If you haven't made the class immutable (there is a performance penalty for not doing that, in addition to my concerns about changing class definitions on the fly), you should be able to do that by getting the meta class for the object (using
$meta = $object->meta
) and using theadd_attribute
method in Class::MOP::Class.Output:
如果您想向对象而不是整个类添加方法,请查看类似
MooseX::SingletonMethod
。例如
,上面的方法
baz
仅添加到对象$foo
中,而不添加到类Foo
中。嗯...我想知道我是否可以实现 MooseX::SingletonAttribute?
之前的一些 SO 答案使用
MooseX::SingletonMethod
:而且这篇博客文章可能有用并且/或兴趣:简单匿名对象
/I3az/
Just in case you want to add a method to an object and not to the whole class then have a look at something like
MooseX::SingletonMethod
.E.g.
So in above the method
baz
is only added to the object$foo
and not to classFoo
.Hmmm... I wonder if I could implement a MooseX::SingletonAttribute?
Some previous SO answer using
MooseX::SingletonMethod
:And also this blog post maybe of use and/or interest: Easy Anonymous Objects
/I3az/
即使在运行时修改类不是一个好的做法,您也可以简单地使元类可变,添加属性并再次使类不可变:
Even if it's not a good pratice to modify a class at runtime, you can simply make the meta-class mutable, add the attribute(s) and make class immutable again: