6

私はMooseオブジェクトを持っています:

class My::Game {
  has 'players' => (isa => 'Set::Object', ...)
  has 'action_sequence' => (isa => 'ArrayRef[My::Game::Action]', ...)
}

$game2 = $game->clone;ここで、ArrayRef 内のオブジェクトが複製されるように、How do I deep clone it so that the objects in the ArrayRef? のような呼び出しでこのオブジェクトを複製できるようにしたいと考えています。さらにトリッキーなことに、Set::Object ?

MooseX::Cloneを見てきましたが、このケースに適用する方法がわかりません。サンプルコードをいただければ幸いです。

ありがとう!

4

2 に答える 2

5

私はここでどの部分 ( MooseX::CloneMooseX::Compile、およびSet::Object ) も使用していないので、ドキュメントと一般的な知識のレビューから、どこから始めればよいかの大まかな概要を以下に示します。 Mooseアーキテクチャの:

  • MooseX::Clone は、オブジェクトに clone() メソッドを提供します。このメソッドは、'Clone' トレイトを持つ属性ごとに clone() を呼び出します。
  • したがって、両方の属性に clone() メソッドを追加する必要があります...
  • MooseX::Clone がネイティブ アトリビュート arrayrefsを処理できることは私の野心的な希望ですが、おそらくそうではないため、その機能を自分で拡張することができます (つまり、'action_sequence' にオプションがある場合、クローンが十分にスマートです)。メソッドは実際に定義されています -- つまり、各メンバー要素で clone() を呼び出して属性を複製します) -- ここはおそらく最初のパッチを送信する場所ですtraits => ['Array']handles => { clone => [ 'map', 'clone' ] }
  • Set::Objectのドキュメントでは、 Storable::dcloneを使用してオブジェクトを確実に複製できることが示唆されています(これを確認し、これが正しくない場合は作成者を非難するか、パッチを提供する必要があります)。
  • 次に、clone() メソッドを Set::Object 属性に追加する必要があります。ドキュメントでは、MooseX::Compileを使用することを推奨しています(ここが irc.perl.org #moose に来て、後でドキュメンタリーを作成できるように、あなたの進歩を一撃一撃で記録してください) :)
于 2010-08-21T16:44:26.903 に答える
2

MooseX::Cloneクラスにロールを追加するだけで、clone()属性を再帰的に複製するメソッドが提供されることがわかりました。

  • hashref/arrayref 属性の場合、構造体をコピーします。
  • スカラー (参照を含む) の場合、単に参照の浅いコピーを行います。
  • 属性に追加traits => ['Clone']すると、属性値を呼び出して属性を再帰的に複製しclone()ます。

クローン作成をサポートするために、クローン作成前に型を強制的に変換する型でパラメーター化された、特性をサブクラス化することによってSet::Object呼び出される特性を作成することになりました。CloneByCoercionClone

だからそれを使うために、私は書いた:

has 'blah' => (isa => 'Set::Object', is => rw,
  traits => ['CloneByCoercion' => {to=>'ArrayRef'}]
);

MooseX::Types::Set::ObjectArrayRef との間の強制を提供します (ただし、バグにパッチを当てる必要がありました: ArrayRef への強制は、リストではなく参照を返す必要があります)

MooseX::Cloneまた、オブジェクトから見えるハッシュを保持するように変更し、循環参照を使用して相互リンクされたオブジェクト構造のクローン作成をサポートするようにしました。

最終的には、このようなものを CPAN に載せたり、モジュールにパッチを提出したりします。

于 2010-08-25T07:35:36.900 に答える