Search code examples
perloopdeep-copybless

Perl: How to deep copy a blessed object?


I'm looking to do a deep (at this point, shallow may suffice) copy of a blessed object.

Foo Class

package Foo;
our $FOO = new Foo;       # initial run

sub new {
   my $class = shift;
   my $self  = {};
   bless $self, $class;
   return $self;
}

Main Program

use Foo;
my $copy = $Foo::FOO;     # instead of creating a ref, want to deep copy here
$copy->{bar} = 'bar';

bar appears in both $Foo::FOO and $copy. I realize I could create a copy of the object by setting it up as $copy = { %{$Foo::FOO} }, but then it would no longer be blessed; additionally, this would only work for simple data structures (right now not an issue). Is the only way to copy this way and then bless after (eg $copy = bless { %{$Foo::FOO} }, q{Foo};)?

I'm trying to avoid using Moose, Clone, or other non-Core modules/packages, so please keep that in mind when replying. Bolded so it stands out more :)


Solution

  • The copying should be part of the API. The user of your module would never know what special actions are required upon creation of a new object (consider registering each object in a my hash in your package).

    Therefore, provide a clone method for your objects. Inside it, you can use any dirty tricks you like:

    sub clone {
        my $self = shift;
        my $copy = bless { %$self }, ref $self;
        $register{$copy} = localtime; # Or whatever else you need to do with a new object.
        # ...
        return $copy;
    }