[Catalyst] Deep copying (was: A couple questions...)

Garrett Goebel ggoebel at goebel.ws
Fri Sep 8 07:18:12 CEST 2006


On Sep 7, 2006, at 4:14 PM, Nate Wiger wrote:

> Dylan Vanderhoof wrote:
>>
>> First question, is it possible to deep-copy a structure using TT?
>
> Check Storable's dclone, or search CPAN for "clone". Or, use this for
> simple structures:
>
>     # Anon copies of arrays/hashes
>     # Based on deep_copy example by merlyn
>     # http://www.stonehenge.com/merlyn/UnixReview/col30.html
>     sub deep_copy {
>         my $orig = shift;
>         return (ref $orig eq 'HASH')
>              ?  +{map { $_ => deep_copy($orig->{$_}) } keys %$orig}
>              : (ref $orig eq 'ARRAY') ? [map deep_copy($_), @$orig]
>              : $orig;
>     }
>
>

If you want to support Tie::RefHash and avoid circular references  
you'll need something like:

local_scope: {
     my %seen = ();
     my $depth = 0;

     sub deep_copy {
         my $ref = ref($_[0]) or return $_[0];
         return $seen{$_[0]}  if $seen{$_[0]};
         $depth++;

         my $rval = $ref eq 'HASH'  ? +{ map { deep_copy($_) } %{$_ 
[0]} }
                  : $ref eq 'ARRAY' ?  [ map { deep_copy($_) } @{$_ 
[0]} ]
                  :                    $_[0] # shallow copy
                  ;

         --$depth and $seen{$_} = rval or %seen = ();
         return $rval;
     }
}

cheers,

Garrett

P.S. while you're at it you might also want to add a check for  
UNIVERSAL::can 'clone'... But by that time you should probably be  
using whatever CPAN has to offer.



More information about the Catalyst mailing list