File Coverage

blib/lib/Class/MakeMethods/Template/Ref.pm
Criterion Covered Total %
statement 21 62 33.8
branch 3 20 15.0
condition 0 3 0.0
subroutine 7 15 46.6
pod 3 3 100.0
total 34 103 33.0


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Class::MakeMethods::Template::Ref - Universal copy and compare methods
4              
5             =head1 SYNOPSIS
6              
7             package MyObject;
8             use Class::MakeMethods::Template::Ref (
9             'Hash:new' => [ 'new' ],
10             clone => [ 'clone' ]
11             );
12            
13             package main;
14              
15             my $obj = MyObject->new( foo => ["Foozle", "Bozzle"] );
16             my $clone = $obj->clone();
17             print $obj->{'foo'}[1];
18              
19             =cut
20              
21             package Class::MakeMethods::Template::Ref;
22              
23             $VERSION = 1.008;
24 1     1   20165 use strict;
  1         4  
  1         49  
25             require 5.00;
26 1     1   7 use Carp;
  1         2  
  1         81  
27              
28 1     1   1165 use Class::MakeMethods::Template '-isasubclass';
  1         4  
  1         14  
29 1     1   1158 use Class::MakeMethods::Utility::Ref qw( ref_clone ref_compare );
  1         4  
  1         7  
30              
31             ######################################################################
32              
33             =head1 DESCRIPTION
34              
35             The following types of methods are provided via the Class::MakeMethods interface:
36              
37             =head2 clone
38              
39             Produce a deep copy of an instance of almost any underlying datatype.
40              
41             Parameters:
42              
43             init_method
44            
45             If defined, this method is called on the new object with any arguments passed in.
46              
47             =cut
48              
49             sub clone {
50             {
51             'params' => { 'init_method' => '' },
52             'interface' => {
53             default => 'clone',
54             clone => { '*'=>'clone', },
55             },
56             'behavior' => {
57 1     1   2 'clone' => sub { my $m_info = $_[0]; sub {
58 1     1   6855 my $callee = shift;
59 1 50       10 ref $callee or croak "Can only copy instances, not a class.\n";
60            
61 1         7 my $self = ref_clone( $callee );
62            
63 1         5 my $init_method = $m_info->{'init_method'};
64 1 50       6 if ( $init_method ) {
    50          
65 0         0 $self->$init_method( @_ );
66             } elsif ( scalar @_ ) {
67 0         0 croak "No init_method";
68             }
69 1         7 return $self;
70 1         5 }},
71             },
72             }
73 1     1 1 15 }
74              
75             ######################################################################
76              
77             =head2 prototype
78              
79             Create new instances by making a deep copy of a static prototypical instance.
80              
81             Parameters:
82              
83             init_method
84            
85             If defined, this method is called on the new object with any arguments passed in.
86             =cut
87              
88             sub prototype {
89             ( {
90             'interface' => {
91             default => { '*'=>'set_or_new', },
92             },
93             'behavior' => {
94 0     0     'set_or_new' => sub { my $m_info = $_[0]; sub {
95 0           my $class = shift;
96            
97 0 0 0       if ( scalar @_ == 1 and UNIVERSAL::isa( $_[0], $class ) ) {
98             # set
99 0           $m_info->{'instance'} = shift
100            
101             } else {
102             # get
103 0 0         croak "Prototype is not defined" unless $m_info->{'instance'};
104 0           my $self = ref_clone($m_info->{'instance'});
105            
106 0           my $init_method = $m_info->{'init_method'};
107 0 0         if ( $init_method ) {
    0          
108 0           $self->$init_method( @_ );
109             } elsif ( scalar @_ ) {
110 0           croak "No init_method";
111             }
112 0           return $self;
113             }
114 0           }},
115 0     0     'set' => sub { my $m_info = $_[0]; sub {
116 0           my $class = shift;
117 0           $m_info->{'instance'} = shift
118 0           }},
119 0     0     'new' => sub { my $m_info = $_[0]; sub {
120 0           my $class = shift;
121            
122 0 0         croak "Prototype is not defined" unless $m_info->{'instance'};
123 0           my $self = ref_clone($m_info->{'instance'});
124            
125 0           my $init_method = $m_info->{'init_method'};
126 0 0         if ( $init_method ) {
    0          
127 0           $self->$init_method( @_ );
128             } elsif ( scalar @_ ) {
129 0           croak "No init_method";
130             }
131 0           return $self;
132 0           }},
133             },
134             } )
135 0     0 1   }
136              
137             ######################################################################
138              
139             =head2 compare
140              
141             Compare one object to another.
142              
143             B
144              
145             =over 4
146              
147             =item *
148              
149             default
150              
151             Three-way (sorting-style) comparison.
152              
153             =item *
154              
155             equals
156              
157             Are these two objects equivalent?
158              
159             =item *
160              
161             identity
162              
163             Are these two references to the exact same object?
164              
165             =back
166              
167             =cut
168              
169             sub compare {
170             {
171             'params' => { 'init_method' => '' },
172             'interface' => {
173             default => { '*'=>'compare', },
174             equals => { '*'=>'equals', },
175             identity => { '*'=>'identity', },
176             },
177             'behavior' => {
178 0     0     'compare' => sub { my $m_info = $_[0]; sub {
179 0           my $callee = shift;
180 0           ref_compare( $callee, shift );
181 0           }},
182 0     0     'equals' => sub { my $m_info = $_[0]; sub {
183 0           my $callee = shift;
184 0           ref_compare( $callee, shift ) == 0;
185 0           }},
186 0     0     'identity' => sub { my $m_info = $_[0]; sub {
187 0           $_[0] eq $_[1]
188 0           }},
189             },
190             }
191 0     0 1   }
192              
193             ######################################################################
194              
195             =head1 SEE ALSO
196              
197             See L for general information about this distribution.
198              
199             See L for more about this family of subclasses.
200              
201             See L for the clone and compare functions used above.
202              
203             =cut
204              
205             ######################################################################
206              
207             1;