我有一个Moose对象:
class My::Game {
has 'players' => (isa => 'Set::Object', ...)
has 'action_sequence' => (isa => 'ArrayRef[My::Game::Action]', ...)
}
现在我希望能够通过像$game2 = $game->clone;
这样的调用来克隆这个对象。如何深度克隆它以便克隆ArrayRef中的对象?更巧妙的是,Set::Object?
我看过MooseX::Clone,但我不清楚如何将它应用于此案例。示例代码将不胜感激。
谢谢!
答案 0 :(得分:5)
我没有使用过此处的任何内容(MooseX::Clone,MooseX::Compile和Set::Object),所以这里只是我从哪里开始的大致轮廓,从我的评论Moose建筑的文献和一般知识:
traits => ['Array']
,它足够聪明,克隆方法实际上是通过handles => { clone => [ 'map', 'clone' ] }
定义的 - 即通过在每个成员元素上调用clone()来克隆属性) - 这里很可能您将在哪里提交第一个补丁答案 1 :(得分:2)
事实证明,简单地将MooseX::Clone
角色添加到类中会提供递归克隆属性的clone()
方法。
traits => ['Clone']
,它将通过在属性值上调用clone()
来递归克隆该属性。为了支持克隆Set::Object
,我最终创建了一个名为CloneByCoercion
的特征,通过继承Clone
特征,在克隆之前使用类型进行参数化以强制进出/。
为了使用它,我写道:
has 'blah' => (isa => 'Set::Object', is => rw,
traits => ['CloneByCoercion' => {to=>'ArrayRef'}]
);
MooseX::Types::Set::Object
向ArrayRef提供强制攻击(尽管我需要修补其中的错误:对ArrayRef的强制应该返回引用,而不是列表)
我还修改了MooseX::Clone
以保持对象看到的哈希值,以便它支持使用循环引用克隆相互链接的对象结构。
我最终会把这些东西放在CPAN上或者向模块提交补丁。