File Coverage

blib/lib/Phaylon/Class/Cloner.pm
Criterion Covered Total %
statement 15 38 39.4
branch 0 4 0.0
condition 0 13 0.0
subroutine 5 11 45.4
pod 2 2 100.0
total 22 68 32.3


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Phaylon::Class::Cloner - Experimental Customizable Cloning Device
4              
5             =cut
6              
7             package Phaylon::Class::Cloner;
8 1     1   34688 use warnings;
  1         2  
  1         30  
9 1     1   5 use strict;
  1         2  
  1         31  
10              
11 1     1   6 use Carp;
  1         6  
  1         94  
12 1     1   1173 use Storable qw/ dclone /;
  1         4341  
  1         79  
13 1     1   7 use vars qw/ $VERSION /;
  1         2  
  1         416  
14              
15             $VERSION = 0.01;
16              
17             =head1 SYNOPSIS
18              
19             use Phaylon::Class::Cloner;
20              
21             # that's what I needed
22             my $cloner = Phaylon::Class::Cloner->new ({
23            
24             CODE => sub {
25             my ( $self, $coderef ) = @_;
26             return $coderef;
27             },
28             });
29              
30             # cloning something
31             my $cloned = $cloner->clone( $structure );
32              
33             =head1 DESCRIPTION
34              
35             I had problems with cloning of structures that contain coderefs. I didn't
36             need to clone coderefs, just array and hash references. This module enables
37             one to define custom specific and default cloning functionalities.
38              
39             =head1 PUBLIC METHODS
40              
41             =cut
42              
43             sub new {
44 0     0 1   my ( $class, $options ) = @_;
45 0 0         croak 'First argument should be option hash reference'
46             unless ref $options eq 'HASH';
47              
48 0   0       $options->{HASH} ||= \&_clone_HASH;
49 0   0       $options->{ARRAY} ||= \&_clone_ARRAY;
50 0   0       $options->{ '' } ||= \&_clone_plain_scalar;
51 0   0       $options->{ ':default' } ||= \&_clone_default;
52              
53 0           my $self = bless $options, $class;
54 0           return $self;
55             }
56              
57             =head2 new( I )
58              
59             Creates a new cloning object. Here's a quick example to show what can
60             be passed:
61              
62             my $cloner = Phaylon::Class::Cloner->new ({
63              
64             # if the module finds a coderef
65             CODE => sub { ... },
66              
67             # module ran into an object
68             MyClass => sub {
69             my ( $self, $object ) = @_;
70             return $object->some_cloning_mechanism;
71             },
72              
73             # what to do for non-refs. default is just to
74             # return the value
75             '' => sub { ... },
76              
77             # if nothing's found for this type. preset to use
78             # Storage::dclone()
79             ':default' => sub { ... },
80             });
81              
82             =cut
83              
84             sub clone {
85 0     0 1   my ( $self, $struct ) = @_;
86              
87 0   0       my $key = ( ref $struct || '' );
88 0   0       my $code = $self->{ $key }
89             || $self->{ ':default' };
90              
91 0 0         croak "No coderef behind $key" unless ref $code eq 'CODE';
92            
93 0           return $self->$code( $struct );
94             }
95              
96             =head2 clone( I )
97              
98             Dispatcher for cloning functionality.
99              
100             =head1 INTERNAL METHODS
101              
102             =cut
103              
104             sub _clone_default {
105 0     0     my ( $self, $struct ) = @_;
106 0           return dclone( $struct );
107             }
108              
109             =head2 _clone_default
110              
111             Preset default cloning. Uses L's C
112              
113             =cut
114              
115             sub _clone_plain_scalar {
116 0     0     my ( $self, $struct ) = @_;
117 0           return $struct;
118             }
119              
120             =head2 _clone_plain_scalar
121              
122             Cloning for non-reference scalars. Defaults to return the value.
123              
124             =cut
125              
126             sub _clone_HASH {
127 0     0     my ( $self, $struct ) = @_;
128              
129             return {
130 0           map { ( $_ => $self->clone( $struct->{ $_ } ) ) }
  0            
131             keys %$struct
132             };
133             }
134              
135             =head2 _clone_HASH
136              
137             Default for hash references. Clones first level with redispatching
138             values to C.
139              
140             =cut
141              
142             sub _clone_ARRAY {
143 0     0     my ( $self, $struct ) = @_;
144 0           return [ map { $self->clone( $_ ) } @$struct ];
  0            
145             }
146              
147             =head2 _clone_ARRAY
148              
149             Same as C<_clone_HASH> just for arrays.
150              
151             =head1 REQUIRES
152              
153             L, L
154              
155             =head1 SEE ALSO
156              
157             L
158              
159             =head1 NAMESPACE
160              
161             Due to the specific and experimental nature of this module, it's trying not to waste
162             namespaces and therefore lies under C.
163              
164             =head1 LICENSE
165              
166             This module is free software. It may be used, redistributed and/or modified under the same
167             terms as Perl itself.
168              
169             =head1 AUTHOR AND COPYRIGHT
170              
171             Copyright (c) 2005: Robert Sedlacek C
172              
173             =cut
174              
175             1;
176