I've got a Moose object:
class My::Game {
has 'players' => (isa => 'Set::Object', ...)
has 'action_sequence' => (isa => 'ArrayRef[My::Game::Action]', ...)
}
Now I want to be able to clone this object with a call like $game2 = $game->clone;
How do I deep clone it so that the objects in the ArrayRef are cloned? And more trickily, the Set::Object?
I've looked at MooseX::Clone, but I'm unclear how to apply it to this case. Example code would be appreciated.
Thanks!
Copy an Object With Object. assign() was the most popular way to deep copy an object. Object. assign() will copy everything into the new object, including any functions. Mutating the copied object also doesn't affect the original object.
To clone an object, use the Object class's clone() method. It is the quickest way to duplicate an array. The class whose object clone we wish to generate must implement the Cloneable interface. If the Cloneable interface is not implemented, the clone() function throws a CloneNotSupportedException .
cloneDeep() method is used to create a deep copy of the value i.e. it recursively clones the value. This method is similar to the _.
Cloning. Cloning in javascript is nothing but copying an object properties to another object so as to avoid creation of an object that already exists. There are a few ways to clone a javascript object. 1) Iterating through each property and copy them to a new object. 2) Using JSON method.
I haven't used any of the pieces here (MooseX::Clone, MooseX::Compile, and Set::Object), so here's just a rough outline of where I'd start, from my review of the docs and general knowledge of Moose architecture:
traits => ['Array']
, it is smart enough that the clone method is actually defined via handles => { clone => [ 'map', 'clone' ] }
-- i.e. clone the attribute by calling clone() on each of the member elements) -- here is likely where you would be submitting your first patchTurns out that simply adding the MooseX::Clone
role to the class provides a clone()
method that recursively clones attributes.
traits => ['Clone']
to the attribute, it will recursively clone the attribute by calling clone()
on the attribute value.To support cloning Set::Object
, I ended up creating a trait called CloneByCoercion
by subclassing the Clone
trait, parameterized with the type to coerce to/from before cloning.
So to use it, I wrote:
has 'blah' => (isa => 'Set::Object', is => rw,
traits => ['CloneByCoercion' => {to=>'ArrayRef'}]
);
MooseX::Types::Set::Object
provides coercions to and from ArrayRef (although I needed to patch a bug in it: the coercion to ArrayRef should return a reference, not a list)
I also modified MooseX::Clone
to keep an objects-seen hash, so that it supports cloning interlinked object structures with circular references.
I'll eventually get around to putting this stuff up on CPAN or submitting patches to the modules.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With