It can be handy to have a clone method so that neighbouring methods are able to make use of a new object based on an existing object. For instance, the code

sub does_something {
    shift unless ref $_[0];
    return $_[0]->merge($_[1]);

might want to clone $_[0] so that existing references to it aren’t modified, such as

sub does_something {
    shift unless ref $_[0];
    return $_[0]->clone->merge($_[1]);

which would merge $_[1] into a clone of $_[0] instead of modifying $_[0] itself.

Often you’ll need a ‘deep’ clone in those situations, which is left for a separate story. But for a shallow copy, the solution is usually cheap and easy: use new.

sub new {
    my ($proto, %param) = @_;
    my $class = ref $proto || $proto;
    my $self = ref($proto) ? { %$proto } : {};
    %$self = (%$self, %param) if %param;
    return bless $self => $class;

That only works for classes where the objects are hashrefs (handling arrayrefs is also easy) and where replacing only the top-level ref is enough.


You were trying to clone oracle instance ORA1 to oracle instance ORA2 using RMAN duplicate, but it failed and now when you connect RMAN it shows them both having name ORA1:

rman target / auxiliary SYS/pissword@ORA2
Recovery Manager: Release - Production on Thu May 26 07:23:06 2011
Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.
connected to target database: ORA1 (DBID=3447699504)
connected to auxiliary database: ORA1 (not mounted)

(the problem is the last line shows ‘ORA1’ instead of ‘ORA2’)
Before the RMAN duplicate failed, rman changed the name of the auxiliary instance to have the name of the original instance (as the first step of the cloning process). To change it back, edit it via its pfile:

create pfile from spfile

Then edit the pfile (eg initORA2.ora) to change the value of db_name from ORA1 to ORA2.
Then apply the change:

shutdown immediate;
create spfile from pfile;
startup nomount;

and re-test the connection via rman to check it now shows ‘ORA2’.