Cloning Objects
Problem
You want to write a constructor method that might be called on an existing object.
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.
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 can be called on the class or an existing object. 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 called 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, $proto);
}
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 ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access