Mercurial > pub > Impl
comparison lib/IMPL/clone.pm @ 407:c6e90e02dd17 ref20150831
renamed Lib->lib
author | cin |
---|---|
date | Fri, 04 Sep 2015 19:40:23 +0300 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
406:f23fcb19d3c1 | 407:c6e90e02dd17 |
---|---|
1 package IMPL::clone; | |
2 | |
3 use Scalar::Util qw(blessed reftype refaddr); | |
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 | |
13 my $new = $_[1]->{ refaddr($_[0]) } = {}; | |
14 while (my ($key,$val) = each %{$_[0]}) { | |
15 $new->{$key} = clone($val,$_[1]); | |
16 } | |
17 $class ? bless $new, $class : $new; | |
18 }, | |
19 ARRAY => sub { | |
20 my $class = blessed($_[0]); | |
21 | |
22 my $new = $_[1]->{ refaddr($_[0]) } = []; | |
23 | |
24 push @$new, clone($_,$_[1]) foreach @{$_[0]}; | |
25 | |
26 $class ? bless( $new, $class ) : $new; | |
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]); | |
36 my $v; | |
37 my $new = $_[1]->{ refaddr($_[0]) } = \$v; | |
38 $v = clone ( ${$_[0]},$_[1] ); | |
39 $class ? bless \$v, $class : \$v; | |
40 | |
41 }, | |
42 REGEXP => sub { | |
43 $_[0]; | |
44 } | |
45 ); | |
46 | |
47 sub clone { | |
48 return unless @_; | |
49 | |
50 return $_[0] unless ref $_[0]; | |
51 | |
52 return $_[1]->{refaddr($_[0])} || (UNIVERSAL::can($_[0],'_clone') || $handlers{reftype($_[0])} || sub { die "Unknown reftype " . reftype($_[0])} )->(@_); | |
53 } | |
54 | |
55 } | |
56 | |
57 1; |