我有一个Moose对象:
class My::Game {
has 'players' => (isa => 'Set::Object', ...)
has 'action_sequence' => (isa => 'ArrayRef[My::Game::Action]', ...)
}
现在我希望能够通过像_1793085这样的调用来克隆这个对象 . 如何深度克隆它以便克隆ArrayRef中的对象?更狡猾的是,Set::Object?
我看了MooseX::Clone,但我不清楚如何将它应用于这种情况 . 示例代码将不胜感激 .
谢谢!
2 回答
我没有使用过这里的任何部分(MooseX::Clone,MooseX::Compile和Set::Object),所以这里's just a rough outline of where I'开始,从我对Moose架构的文档和一般知识的评论开始:
MooseX :: Clone为您的对象提供clone()方法,然后使用'Clone' trait对每个属性调用clone() .
所以,你需要为你的两个属性添加一个clone()方法......
这将是我雄心勃勃的希望,MooseX :: Clone可以处理native attribute arrayrefs,但由于它可能没有't, you may get to extend that feature yourself (i.e. if ' action_sequence'选项
traits => ['Array']
,因此克隆方法实际上是通过handles => { clone => [ 'map', 'clone' ] }
定义的,这很聪明 - 即通过调用克隆属性每个成员元素上的clone()) - 这可能是您提交第一个补丁的地方Set::Object的文档建议您可以使用Storable::dclone可靠地克隆对象(如果这不正确,您应该验证并鞭打作者和/或提供补丁)
现在你需要将一个clone()方法添加到Set :: Object属性中,文档建议你使用MooseX::Compile(这里你应该来irc.perl.org #moose并给我们一个打击 - 你的进步受到了影响,所以我们可以稍后制作一部关于它的纪录片:)
事实证明,只需将
MooseX::Clone
角色添加到类中即可提供递归克隆属性的clone()
方法 .对于hashref / arrayref属性,它复制结构 .
对于标量(包括引用),它只是执行引用的浅表副本 .
如果将
traits => ['Clone']
添加到属性,它将通过在属性值上调用clone()
来递归克隆该属性 .为了支持克隆
Set::Object
,我最终创建了一个名为CloneByCoercion
的特征,通过继承Clone
trait,在克隆之前使用类型进行参数化以强制进/出 .所以要使用它,我写道:
MooseX::Types::Set::Object
向ArrayRef提供强制攻击(尽管我需要修补其中的错误:对ArrayRef的强制应该返回引用,而不是列表)我还修改了
MooseX::Clone
以保持对象看到的散列,以便它支持使用循环引用克隆互连对象结构 .我最终会把这些东西放在CPAN上或者向模块提交补丁 .