X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMouse%2FMeta%2FClass.pm;h=8ecb8282e7268d317964bd70890fa3fcdd0472d9;hb=f7b11a21869769d2b49bba4fa72d33fa54ad0c2e;hp=42f824e57f91d018a6b7908efc210905820f756b;hpb=66eea168570f52254def2675f86706336ab9bd8a;p=gitmo%2FMouse.git diff --git a/lib/Mouse/Meta/Class.pm b/lib/Mouse/Meta/Class.pm index 42f824e..8ecb828 100644 --- a/lib/Mouse/Meta/Class.pm +++ b/lib/Mouse/Meta/Class.pm @@ -4,6 +4,7 @@ use strict; use warnings; use Scalar::Util 'blessed'; +use Carp 'confess'; use MRO::Compat; @@ -29,7 +30,7 @@ do { sub new { my $class = shift; - my %args = @_; + my %args = @_; $args{attributes} = {}; $args{superclasses} = do { @@ -83,6 +84,37 @@ sub get_attribute { $_[0]->{attributes}->{$_[1]} } sub linearized_isa { @{ mro::get_linear_isa($_[0]->name) } } +sub clone_object { + my $class = shift; + my $instance = shift; + + (blessed($instance) && $instance->isa($class->name)) + || confess "You must pass an instance ($instance) of the metaclass (" . $class->name . ")"; + + $class->clone_instance($instance, @_); +} + +sub clone_instance { + my ($class, $instance, %params) = @_; + + (blessed($instance)) + || confess "You can only clone instances, \$self is not a blessed instance"; + + my $clone = bless { %$instance }, ref $instance; + + foreach my $attr ($class->compute_all_applicable_attributes()) { + if ( defined( my $init_arg = $attr->init_arg ) ) { + if (exists $params{$init_arg}) { + $clone->{ $attr->name } = $params{$init_arg}; + } + } + } + + return $clone; + +} + + 1; __END__ @@ -137,5 +169,14 @@ Returns the L with the given name. Returns the list of classes in method dispatch order, with duplicates removed. +=head2 clone_object Instance -> Instance + +Clones the given C which must be an instance governed by this +metaclass. + +=head2 clone_instance Instance, Parameters -> Instance + +Clones the given C and sets any additional parameters. + =cut