First, don't call your method new
call it promote
or something like that.
I have mixed feelings about how to handle this design. My initial reaction is that you should use accessor methods and 'manually' copy the values into a new object.
sub promote {
my $class = shift;
my $obj = shift;
my %args = map { $_ => $obj->$_ } qw(
attribute
another
this_one
that_one
);
return $class->new( %args );
}
This insulates your subclass from changes in the parent.
Your parent class may now be or become an inside out object or something else that does not clone
well. A critical attribute in the parent may be replaced by a method that generates it from other attributes.
Obviously, a degree of coupling between a parent and child class is unavoidable. But this approach helps minimize it.
The other way that seems obvious is to use a clone
and rebless like jkramer suggests. The big problem with this is that you have these restrictions:
- your parent class objects must be clonable
- your parent and child classes must implement storage in identically.
- accessor/mutator methods must not use a class-name prefix for attribute access. This means that class Foo stores
attrib
in $self->{'Foo::attrib'} = 'value';
while Foo::Bar stores them in $self->{'Foo::Bar::attrib'} = 'value';
For cloning, I would use Storable
's dclone
. It has the advantage of being a core module, and many more exotic object implementations provide hooks for Storable so that cloning will work properly.