Recipe 13.6. Cloning Objects
Author: Tom Christiansen & Nathan Torkington
Date: 1999-07-02T01:42:22Z

#

| Chapter 13 Classes, Objects, and Ties |

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

### See Also

perlobj (1) and Chapter 5 of Programming Perl; Recipe 13.1; Recipe 13.9; Recipe 13.13

13.5. Using Classes as Structs |  | 13.7. Calling Methods Indirectly