0.54
* Class::MOP
- metaclass
+ metaclass.pm
- making sure that load_class never gets
passed a value from @_ or $_ to squash
Ovid's bug (http://use.perl.org/~Ovid/journal/35763)
- make_{immutable,mutable} now return 1
(cause Sartak asked)
- improved error handling in ->create method
+ - rebless_instance now takes extra params which
+ will be used to populate values
+ - added tests for this
* Class::MOP::Object
- localizing the Data::Dumper configurations so
}
sub rebless_instance {
- my ($self, $instance) = @_;
+ my ($self, $instance, %params) = @_;
my $old_metaclass;
if ($instance->can('meta')) {
# rebless!
$meta_instance->rebless_instance_structure($instance, $self);
- my %params;
-
foreach my $attr ( $self->compute_all_applicable_attributes ) {
if ( $attr->has_value($instance) ) {
if ( defined( my $init_arg = $attr->init_arg ) ) {
- $params{$init_arg} = $attr->get_value($instance);
- } else {
+ $params{$init_arg} = $attr->get_value($instance)
+ unless exists $params{$init_arg};
+ }
+ else {
$attr->set_value($instance);
}
}
think Yuval "nothingmuch" Kogman put it best when he said that cloning
is too I<context-specific> to be part of the MOP.
-=item B<rebless_instance($instance)>
+=item B<rebless_instance($instance, ?%params)>
This will change the class of C<$instance> to the class of the invoking
C<Class::MOP::Class>. You may only rebless the instance to a subclass of
-itself.
+itself. You may pass in optional C<%params> which are like constructor
+params and will override anything already defined in the instance.
=back
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More tests => 22;
+use Test::Exception;
+
+BEGIN {
+ use_ok('Class::MOP');
+}
+
+{
+ package Foo;
+ use metaclass;
+ Foo->meta->add_attribute('bar' => (reader => 'bar'));
+
+ sub new { (shift)->meta->new_object(@_) }
+
+ package Bar;
+ use metaclass;
+ use base 'Foo';
+ Bar->meta->add_attribute('baz' => (reader => 'baz', default => 'BAZ'));
+}
+
+# normal ...
+{
+ my $foo = Foo->new(bar => 'BAR');
+ isa_ok($foo, 'Foo');
+
+ is($foo->bar, 'BAR', '... got the expect value');
+ ok(!$foo->can('baz'), '... no baz method though');
+
+ lives_ok {
+ Bar->meta->rebless_instance($foo)
+ } '... this works';
+
+ is($foo->bar, 'BAR', '... got the expect value');
+ ok($foo->can('baz'), '... we have baz method now');
+ is($foo->baz, 'BAZ', '... got the expect value');
+}
+
+# with extra params ...
+{
+ my $foo = Foo->new(bar => 'BAR');
+ isa_ok($foo, 'Foo');
+
+ is($foo->bar, 'BAR', '... got the expect value');
+ ok(!$foo->can('baz'), '... no baz method though');
+
+ lives_ok {
+ Bar->meta->rebless_instance($foo, (baz => 'FOO-BAZ'))
+ } '... this works';
+
+ is($foo->bar, 'BAR', '... got the expect value');
+ ok($foo->can('baz'), '... we have baz method now');
+ is($foo->baz, 'FOO-BAZ', '... got the expect value');
+}
+
+# with extra params ...
+{
+ my $foo = Foo->new(bar => 'BAR');
+ isa_ok($foo, 'Foo');
+
+ is($foo->bar, 'BAR', '... got the expect value');
+ ok(!$foo->can('baz'), '... no baz method though');
+
+ lives_ok {
+ Bar->meta->rebless_instance($foo, (bar => 'FOO-BAR', baz => 'FOO-BAZ'))
+ } '... this works';
+
+ is($foo->bar, 'FOO-BAR', '... got the expect value');
+ ok($foo->can('baz'), '... we have baz method now');
+ is($foo->baz, 'FOO-BAZ', '... got the expect value');
+}
+
+