
![]() | ![]() |
13.6. Cloning Constructors
13.6.1. Problem
You want to write a constructor method
that might be invoked on an existing object, and if so, to use that
object for default values.
13.6.2. Solution
Start your constructor like this:my $proto = shift;
my $class = ref($proto) || $proto;
my $parent = ref($proto) && $proto;
The $class variable will contain the class to
bless into, and the $parent variable will either
be false, or else the object you're cloning.
13.6.3. Discussion
Sometimes you need another object of the same type as the current
one. You could do this:$ob1 = SomeClass->new( );
# later on
$ob2 = (ref $ob1)->new( );
but that's not very clear. It's clearer to have a single constructor
that behaves correctly, regardless of whether its invocant is a class
name or an existing object of that class. As a class method, it
should return a new object with the default initialization. As an
instance method, it should return a new object initialized from the
object it was invoked on:$ob1 = Widget->new( );
$ob2 = $ob1->new( );
Here's a version of new that takes this into
consideration:sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $parent = ref($proto) && $proto;
my $self;
# check whether we're shadowing a new from @ISA
if (@ISA && $proto->SUPER::can("new") ) {
$self = $proto->SUPER::new(@_);
} else {
$self = { };
bless ($self, $class);
}
$self->{PARENT} = $parent;
$self->{START} = time( ); # init data fields
$self->{AGE} = 0;
return $self;
}
Initializing doesn't have to mean simply copying values from the
parent. If you're writing a linked list or binary tree class, your
constructor can return a new object linked into the list or tree,
when invoked as an instance method.
13.6.4. See Also
perlobj(1) and Chapter 12 of
Programming Perl; Recipe 13.1; Recipe 13.10; Recipe 13.13
![]() | ![]() | ![]() |
13.5. Using Classes as Structs | ![]() | 13.7. Copy Constructors |

Copyright © 2003 O'Reilly & Associates. All rights reserved.