File Coverage

blib/lib/Class/MakeMethods/Template/Hash.pm
Criterion Covered Total %
statement 50 52 96.1
branch 6 10 60.0
condition 9 15 60.0
subroutine 12 12 100.0
pod 2 3 66.6
total 79 92 85.8


line stmt bran cond sub pod time code
1             package Class::MakeMethods::Template::Hash;
2              
3 64     64   398439 use Class::MakeMethods::Template::Generic '-isasubclass';
  64         237  
  64         3451  
4              
5             $VERSION = 1.008;
6 64     64   1068 use strict;
  64         135  
  64         57030  
7             require 5.0;
8              
9             sub generic {
10             {
11 69     69 0 1765 'params' => {
12             'hash_key' => '*',
13             },
14             'code_expr' => {
15             _VALUE_ => '_SELF_->{_STATIC_ATTR_{hash_key}}',
16             '-import' => { 'Template::Generic:generic' => '*' },
17             _EMPTY_NEW_INSTANCE_ => 'bless {}, _SELF_CLASS_',
18             _SET_VALUES_FROM_HASH_ => 'while ( scalar @_ ) { local $_ = shift(); $self->{ $_ } = shift() }'
19             },
20             'behavior' => {
21             'hash_delete' => q{ delete _VALUE_ },
22             'hash_exists' => q{ exists _VALUE_ },
23             },
24             'modifier' => {
25             # XXX the below doesn't work because modifiers can't have params,
26             # although interfaces can... Either add support for default params
27             # in modifiers, or else move this to another class.
28             # X Should there be a version which uses caller() instead of target_class?
29             'class_keys' => { 'hash_key' => '"*{target_class}::*{name}"' },
30             }
31             }
32             }
33              
34             ########################################################################
35              
36             =head1 NAME
37              
38             Class::MakeMethods::Template::Hash - Method interfaces for hash-based objects
39              
40             =head1 SYNOPSIS
41              
42             package MyObject;
43             use Class::MakeMethods::Template::Hash (
44             new => [ 'new' ],
45             scalar => [ 'foo', 'bar' ]
46             );
47            
48             package main;
49              
50             my $obj = MyObject->new( foo => "Foozle", bar => "Bozzle" );
51             print $obj->foo();
52             $obj->bar("Bamboozle");
53              
54             =head1 DESCRIPTION
55              
56             These meta-methods create and access values within blessed hash objects.
57              
58             B: The following parameters are defined for Hash meta-methods.
59              
60             =over 4
61              
62             =item hash_key
63              
64             The hash key to use when retrieving values from each hash instance. Defaults to '*', the name of the meta-method.
65              
66             Changing this allows you to change an accessor method name to something other than the name of the hash key used to retrieve its value.
67              
68             Note that this parameter is not portable to the other implementations, such as Global or InsideOut.
69              
70             You can take advantage of parameter expansion to define methods whose hash key is composed of the defining package's name and the individual method name, such as C<$self-E{I-I}>:
71              
72             'hash_key' => '*{target_class}-*{name}'
73              
74             =back
75              
76             B
77              
78             =over 4
79              
80             =item Behavior: delete
81              
82             Deletes the named key and associated value from the current hash instance.
83              
84             =back
85              
86             =head2 Standard Methods
87              
88             The following methods from Generic are all supported:
89              
90             new
91             scalar
92             string
93             string_index
94             number
95             boolean
96             bits (*)
97             array
98             hash
99             tiedhash
100             hash_of_arrays
101             object
102             instance
103             array_of_objects
104             code
105             code_or_scalar
106              
107             See L for the interfaces and behaviors of these method types.
108              
109             The items marked with a * above are specifically defined in this package, whereas the others are formed automatically by the interaction of this package's generic settings with the code templates provided by the Generic superclass.
110              
111             =cut
112              
113             # This is the only one that needs to be specifically defined.
114             sub bits {
115             {
116 3     3 1 21 '-import' => { 'Template::Generic:bits' => '*' },
117             'params' => {
118             'hash_key' => '*{target_class}__*{template_name}',
119             },
120             }
121             }
122              
123             ########################################################################
124              
125             =head2 struct
126              
127             struct => [ qw / foo bar baz / ];
128              
129             Creates methods for setting, checking and clearing values which
130             are stored by position in an array. All the slots created with this
131             meta-method are stored in a single array.
132              
133             The argument to struct should be a string or a reference to an
134             array of strings. For each string meta-method x, it defines two
135             methods: I and I. x returns the value of the x-slot.
136             If called with an argument, it first sets the x-slot to the argument.
137             clear_x sets the slot to undef.
138              
139             Additionally, struct defines three class method: I, which returns
140             a list of all of the struct values, I, which returns
141             a list of all the slots by name, and I, which returns a hash of
142             the slot-name/slot-value pairs.
143              
144             =cut
145              
146             sub struct {
147             ( {
148             'interface' => {
149             default => {
150             '*'=>'get_set', 'clear_*'=>'clear',
151             'struct_fields'=>'struct_fields',
152             'struct'=>'struct', 'struct_dump'=>'struct_dump'
153             },
154             },
155             'params' => {
156             'hash_key' => '*{target_class}__*{template_name}',
157             },
158             'behavior' => {
159             '-init' => sub {
160 10     10   16 my $m_info = $_[0];
161            
162 10   33     44 $m_info->{class} ||= $m_info->{target_class};
163            
164 10   100     81 my $class_info =
165             ($Class::MakeMethods::Template::Hash::struct{$m_info->{class}} ||= []);
166 10 50       32 if ( ! defined $m_info->{sfp} ) {
167 10         26 foreach ( 0..$#$class_info ) {
168 20 50       60 if ( $class_info->[$_] eq $m_info->{'name'} ) {
169 0         0 $m_info->{sfp} = $_;
170             last
171 0         0 }
172             }
173 10 50       28 if ( ! defined $m_info->{sfp} ) {
174 10         16 push @$class_info, $m_info->{'name'};
175 10         33 $m_info->{sfp} = $#$class_info;
176             }
177             }
178 10         35 return;
179             },
180            
181 10     10   14 'struct_fields' => sub { my $m_info = $_[0]; sub {
182 2   50 2   21 my $class_info =
183             ( $Class::MakeMethods::Template::Hash::struct{$m_info->{class}} ||= [] );
184 2         29 @$class_info;
185 10         49 }},
186 10     10   15 'struct' => sub { my $m_info = $_[0]; sub {
187 2         1119 my $self = shift;
188 2   50     12 $self->{$m_info->{hash_key}} ||= [];
189 2 50       9 if ( @_ ) { @{$self->{$m_info->{hash_key}}} = @_ }
  2         6  
  2         8  
190 2         5 @{$self->{$m_info->{hash_key}}};
  2         23  
191 10         45 }},
192 10     12   13 'struct_dump' => sub { my $m_info = $_[0]; sub {
193 2         7 my $self = shift;
194 2   50     12 my $class_info =
195             ( $Class::MakeMethods::Template::Hash::struct{$m_info->{class}} ||= [] );
196 2         7 map { ($_, $self->$_()) } @$class_info;
  10         22  
197 10         67 }},
198            
199 10     12   15 'get_set' => sub { my $m_info = $_[0]; sub {
200 27         1210 my $self = shift;
201 27   100     104 $self->{$m_info->{hash_key}} ||= [];
202            
203 27 100       59 if ( @_ ) {
204 2         9 $self->{$m_info->{hash_key}}->[ $m_info->{sfp} ] = shift;
205             }
206 27         129 $self->{$m_info->{hash_key}}->[ $m_info->{sfp} ];
207 10         61 }},
208 10     37   14 'clear' => sub { my $m_info = $_[0]; sub {
209 2         38 my $self = shift;
210 2   50     12 $self->{$m_info->{hash_key}} ||= [];
211 2         13 $self->{$m_info->{hash_key}}->[ $m_info->{sfp} ] = undef;
212 10         51 }},
213             },
214             } )
215 2     4 1 68 }
216              
217             ########################################################################
218              
219             =head1 SEE ALSO
220              
221             See L for general information about this distribution.
222              
223             See L for more about this family of subclasses.
224              
225             See L for information about the various accessor interfaces subclassed herein.
226              
227             =cut
228              
229             1;