Mercurial > pub > Impl
diff lib/IMPL/clone.pm @ 407:c6e90e02dd17 ref20150831
renamed Lib->lib
author | cin |
---|---|
date | Fri, 04 Sep 2015 19:40:23 +0300 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/IMPL/clone.pm Fri Sep 04 19:40:23 2015 +0300 @@ -0,0 +1,57 @@ +package IMPL::clone; + +use Scalar::Util qw(blessed reftype refaddr); + +use base qw(Exporter); +our @EXPORT_OK = qw(&clone); + +{ + my %handlers = ( + HASH => sub { + my $class = blessed($_[0]); + + my $new = $_[1]->{ refaddr($_[0]) } = {}; + while (my ($key,$val) = each %{$_[0]}) { + $new->{$key} = clone($val,$_[1]); + } + $class ? bless $new, $class : $new; + }, + ARRAY => sub { + my $class = blessed($_[0]); + + my $new = $_[1]->{ refaddr($_[0]) } = []; + + push @$new, clone($_,$_[1]) foreach @{$_[0]}; + + $class ? bless( $new, $class ) : $new; + }, + SCALAR => sub { + my $class = blessed($_[0]); + + my $v = ${$_[0]}; + $class ? bless \$v, $class : \$v; + }, + REF => sub { + my $class = blessed($_[0]); + my $v; + my $new = $_[1]->{ refaddr($_[0]) } = \$v; + $v = clone ( ${$_[0]},$_[1] ); + $class ? bless \$v, $class : \$v; + + }, + REGEXP => sub { + $_[0]; + } + ); + + sub clone { + return unless @_; + + return $_[0] unless ref $_[0]; + + return $_[1]->{refaddr($_[0])} || (UNIVERSAL::can($_[0],'_clone') || $handlers{reftype($_[0])} || sub { die "Unknown reftype " . reftype($_[0])} )->(@_); + } + +} + +1;