home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  

13.6. Cloning Objects


You want to write a constructor method that might be called on an existing object.


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.


Sometimes you need another object of the same type as the current one. You could do this:

$ob1 = SomeClass->
# later on
$ob2 = (ref $ob1)->

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 new object linked into the list or tree, when called as an instance method.

Previous: 13.5. Using Classes as Structs Perl Cookbook Next: 13.7. Calling Methods Indirectly
13.5. Using Classes as Structs Book Index 13.7. Calling Methods Indirectly

Library Navigation Links

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