173
|
1 package IMPL::clone;
|
|
2
|
174
|
3 use Scalar::Util qw(blessed reftype refaddr);
|
173
|
4
|
|
5 use base qw(Exporter);
|
|
6 our @EXPORT_OK = qw(&clone);
|
|
7
|
|
8 {
|
|
9 my %handlers = (
|
|
10 HASH => sub {
|
|
11 my $class = blessed($_[0]);
|
|
12
|
175
|
13 my $new = $_[1]->{ refaddr($_[0]) } = {};
|
173
|
14 while (my ($key,$val) = each %{$_[0]}) {
|
174
|
15 $new->{$key} = clone($val,$_[1]);
|
173
|
16 }
|
|
17 $class ? bless $new, $class : $new;
|
|
18 },
|
|
19 ARRAY => sub {
|
|
20 my $class = blessed($_[0]);
|
175
|
21
|
|
22 my $new = $_[1]->{ refaddr($_[0]) } = [];
|
|
23
|
|
24 push @$new, clone($_,$_[1]) foreach @{$_[0]};
|
|
25
|
|
26 $class ? bless( $new, $class ) : $new;
|
173
|
27 },
|
|
28 SCALAR => sub {
|
|
29 my $class = blessed($_[0]);
|
|
30
|
|
31 my $v = ${$_[0]};
|
|
32 $class ? bless \$v, $class : \$v;
|
|
33 },
|
|
34 REF => sub {
|
|
35 my $class = blessed($_[0]);
|
175
|
36 my $v;
|
|
37 my $new = $_[1]->{ refaddr($_[0]) } = \$v;
|
|
38 $v = clone ( ${$_[0]},$_[1] );
|
173
|
39 $class ? bless \$v, $class : \$v;
|
|
40
|
|
41 },
|
|
42 REGEXP => sub {
|
|
43 $_[0];
|
|
44 }
|
|
45 );
|
174
|
46
|
173
|
47 sub clone {
|
|
48 return unless @_;
|
|
49
|
|
50 return $_[0] unless ref $_[0];
|
|
51
|
181
|
52 return $_[1]->{refaddr($_[0])} || (UNIVERSAL::can($_[0],'_clone') || $handlers{reftype($_[0])} || sub { die "Unknown reftype " . reftype($_[0])} )->(@_);
|
173
|
53 }
|
174
|
54
|
173
|
55 }
|
|
56
|
|
57 1;
|