line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
=head1 NAME |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
Class::MakeMethods::Template::Generic - Templates for common meta-method types |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=head1 SYNOPSIS |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
package MyObject; |
8
|
|
|
|
|
|
|
use Class::MakeMethods ( |
9
|
|
|
|
|
|
|
'Template::Hash:new' => [ 'new' ], |
10
|
|
|
|
|
|
|
'Template::Hash:scalar' => [ 'foo' ] |
11
|
|
|
|
|
|
|
'Template::Static:scalar' => [ 'bar' ] |
12
|
|
|
|
|
|
|
); |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
package main; |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
my $obj = MyObject->new( foo => "Foozle", bar => "Bozzle" ); |
17
|
|
|
|
|
|
|
print $obj->foo(); |
18
|
|
|
|
|
|
|
$obj->bar("Bamboozle"); |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 DESCRIPTION |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
This package provides a variety of abstract interfaces for constructors |
23
|
|
|
|
|
|
|
and accessor methods, which form a common foundation for meta-methods |
24
|
|
|
|
|
|
|
provided by the Hash, Scalar, Flyweight, Static, PackageVar, and |
25
|
|
|
|
|
|
|
ClassVar implementations. |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
Generally speaking, the Generic meta-methods define calling interfaces |
28
|
|
|
|
|
|
|
and behaviors which are bound to differently scoped data by each |
29
|
|
|
|
|
|
|
of those subclasses. |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
=cut |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
######################################################################## |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
package Class::MakeMethods::Template::Generic; |
36
|
|
|
|
|
|
|
|
37
|
89
|
|
|
89
|
|
107307
|
use Class::MakeMethods::Template '-isasubclass'; |
|
89
|
|
|
|
|
321
|
|
|
89
|
|
|
|
|
1515
|
|
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
$VERSION = 1.008; |
40
|
89
|
|
|
89
|
|
1498
|
use strict; |
|
89
|
|
|
|
|
292
|
|
|
89
|
|
|
|
|
3770
|
|
41
|
89
|
|
|
89
|
|
556
|
use Carp; |
|
89
|
|
|
|
|
186
|
|
|
89
|
|
|
|
|
299675
|
|
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
# use AutoLoader 'AUTOLOAD'; |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
######################################################################## |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
sub generic { |
48
|
|
|
|
|
|
|
{ |
49
|
89
|
|
|
89
|
0
|
1839
|
'params' => { |
50
|
|
|
|
|
|
|
}, |
51
|
|
|
|
|
|
|
'modifier' => { |
52
|
|
|
|
|
|
|
'-import' => { 'Template::Universal:generic' => '*' }, |
53
|
|
|
|
|
|
|
}, |
54
|
|
|
|
|
|
|
'code_expr' => { |
55
|
|
|
|
|
|
|
'-import' => { 'Template::Universal:generic' => '*' }, |
56
|
|
|
|
|
|
|
'_VALUE_' => undef, |
57
|
|
|
|
|
|
|
'_REF_VALUE_' => q{ _VALUE_ }, |
58
|
|
|
|
|
|
|
'_GET_VALUE_' => q{ _VALUE_ }, |
59
|
|
|
|
|
|
|
'_SET_VALUE_{}' => q{ ( _VALUE_ = * ) }, |
60
|
|
|
|
|
|
|
'_PROTECTED_SET_VALUE_{}' => q{ (_ACCESS_PROTECTED_ and _SET_VALUE_{*}) }, |
61
|
|
|
|
|
|
|
'_PRIVATE_SET_VALUE_{}' => q{ ( _ACCESS_PRIVATE_ and _SET_VALUE_{*} ) }, |
62
|
|
|
|
|
|
|
}, |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
# 1; |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
# __END__ |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
######################################################################## |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
=head2 new Constructor |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
There are several types of hash-based object constructors to choose from. |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
Each of these methods creates and returns a reference to a new |
77
|
|
|
|
|
|
|
blessed instance. They differ in how their (optional) arguments |
78
|
|
|
|
|
|
|
are interpreted to set initial values, and in how they operate when |
79
|
|
|
|
|
|
|
called as class or instance methods. |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
B: The following interfaces are supported. |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
=over 4 |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
=item -with_values, |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
Provides the with_values behavior. |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
=item -with_init |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
Provides the with_init behavior. |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
=item -with_methods |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
Provides the with_methods behavior. |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
=item -new_and_init |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
Provides the with_init behavior for I<*>, and the general purpose method_init behavior as an init method. |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
=item -copy_with_values |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
Provides the copy behavior. |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
=back |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
B: The following types of constructor methods are available. |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
=over 4 |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
=item with_values |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
Creates and blesses a new instance. |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
If arguments are passed they are included in the instance, otherwise it will be empty. |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
Returns the new instance. |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
May be called as a class or instance method. |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
=item with_methods |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
Creates, blesses, and returns a new instance. |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
The arguments are treated as a hash of method-name/argument-value |
126
|
|
|
|
|
|
|
pairs, with each such pair causing a call C<$self-Ename($value)>. |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
=item with_init |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
Creates and blesses a new instance, then calls a method named C, |
131
|
|
|
|
|
|
|
passing along any arguments that were initially given. |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
Returns the new instance. |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
The I() method should be defined in the class declaring these methods. |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
May be called as a class or instance method. |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
=item and_then_init |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
Creates a new instance using method-name/argument-value pairs, like C, but then calls a method named C before returning the new object. The C method does not receive any arguments. |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
The I() method should be defined in the class declaring these methods. |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
=item instance_with_methods |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
If called as a class method, creates, blesses, and returns a new |
148
|
|
|
|
|
|
|
instance. If called as an object method, operates on and returns |
149
|
|
|
|
|
|
|
the existing instance. |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
Accepts name-value pair arguments, or a reference to hash of such |
152
|
|
|
|
|
|
|
pairs, and calls the named method for each with the supplied value |
153
|
|
|
|
|
|
|
as a single argument. (See the Universal method_init behavior for |
154
|
|
|
|
|
|
|
more discussion of this pattern.) |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
=item copy_with values |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
Produce a copy of an instance. Can not be called as a class method. |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
The copy is a *shallow* copy; any references will be shared by the |
161
|
|
|
|
|
|
|
instance upon which the method is called and the returned newborn. |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
If a list of key-value pairs is passed as arguments to the method, |
164
|
|
|
|
|
|
|
they are added to the copy, overwriting any values with the same |
165
|
|
|
|
|
|
|
key that may have been copied from the original. |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
=item copy_with_methods |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
Produce a copy of an instance. Can not be called as a class method. |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
The copy is a *shallow* copy; any references will be shared by the |
172
|
|
|
|
|
|
|
instance upon which the method is called and the returned newborn. |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
Accepts name-value pair arguments, or a reference to hash of such |
175
|
|
|
|
|
|
|
pairs, and calls the named method on the copy for each with the |
176
|
|
|
|
|
|
|
supplied value as a single argument before the copy is returned. |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
=item copy_instance_with_values |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
If called as a class method, creates, blesses, and returns a new |
181
|
|
|
|
|
|
|
instance. If called as an object method, produces and returns a |
182
|
|
|
|
|
|
|
copy of an instance. |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
The copy is a *shallow* copy; any references will be shared by the |
185
|
|
|
|
|
|
|
instance upon which the method is called and the returned newborn. |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
If a list of key-value pairs is passed as arguments to the method, |
188
|
|
|
|
|
|
|
they are added to the copy, overwriting any values with the same |
189
|
|
|
|
|
|
|
key that may have been copied from the original. |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
=item copy_instance_with_methods |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
If called as a class method, creates, blesses, and returns a new |
194
|
|
|
|
|
|
|
instance. If called as an object method, produces and returns a |
195
|
|
|
|
|
|
|
copy of an instance. |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
The copy is a *shallow* copy; any references will be shared by the |
198
|
|
|
|
|
|
|
instance upon which the method is called and the returned newborn. |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
Accepts name-value pair arguments, or a reference to hash of such |
201
|
|
|
|
|
|
|
pairs, and calls the named method on the copy for each with the supplied value as |
202
|
|
|
|
|
|
|
a single argument before the copy is returned. |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
=back |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
B: The following parameters are supported: |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
=over 4 |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
=item init_method |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
The name of the method to call after creating a new instance. Defaults to 'init'. |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
=back |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
=cut |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
sub new { |
219
|
|
|
|
|
|
|
{ |
220
|
32
|
|
|
32
|
1
|
1265
|
'-import' => { |
221
|
|
|
|
|
|
|
# 'Template::Generic:generic' => '*', |
222
|
|
|
|
|
|
|
}, |
223
|
|
|
|
|
|
|
'interface' => { |
224
|
|
|
|
|
|
|
default => 'with_methods', |
225
|
|
|
|
|
|
|
with_values => 'with_values', |
226
|
|
|
|
|
|
|
with_methods => 'with_methods', |
227
|
|
|
|
|
|
|
with_init => 'with_init', |
228
|
|
|
|
|
|
|
and_then_init => 'and_then_init', |
229
|
|
|
|
|
|
|
new_and_init => { '*'=>'new_with_init', 'init'=>'method_init'}, |
230
|
|
|
|
|
|
|
instance_with_methods => 'instance_with_methods', |
231
|
|
|
|
|
|
|
copy => 'copy_with_values', |
232
|
|
|
|
|
|
|
copy_with_values => 'copy_with_values', |
233
|
|
|
|
|
|
|
copy_with_methods => 'copy_with_methods', |
234
|
|
|
|
|
|
|
copy_instance_with_values => 'copy_instance_with_values', |
235
|
|
|
|
|
|
|
copy_instance_with_methods => 'copy_instance_with_methods', |
236
|
|
|
|
|
|
|
}, |
237
|
|
|
|
|
|
|
'behavior' => { |
238
|
|
|
|
|
|
|
'with_methods' => q{ |
239
|
|
|
|
|
|
|
$self = _EMPTY_NEW_INSTANCE_; |
240
|
|
|
|
|
|
|
_CALL_METHODS_FROM_HASH_ |
241
|
|
|
|
|
|
|
return $self; |
242
|
|
|
|
|
|
|
}, |
243
|
|
|
|
|
|
|
'with_values' => q{ |
244
|
|
|
|
|
|
|
$self = _EMPTY_NEW_INSTANCE_; |
245
|
|
|
|
|
|
|
_SET_VALUES_FROM_HASH_ |
246
|
|
|
|
|
|
|
return $self; |
247
|
|
|
|
|
|
|
}, |
248
|
|
|
|
|
|
|
'with_init' => q{ |
249
|
|
|
|
|
|
|
$self = _EMPTY_NEW_INSTANCE_; |
250
|
|
|
|
|
|
|
my $init_method = $m_info->{'init_method'} || 'init'; |
251
|
|
|
|
|
|
|
$self->$init_method( @_ ); |
252
|
|
|
|
|
|
|
return $self; |
253
|
|
|
|
|
|
|
}, |
254
|
|
|
|
|
|
|
'and_then_init' => q{ |
255
|
|
|
|
|
|
|
$self = _EMPTY_NEW_INSTANCE_; |
256
|
|
|
|
|
|
|
_CALL_METHODS_FROM_HASH_ |
257
|
|
|
|
|
|
|
my $init_method = $m_info->{'init_method'} || 'init'; |
258
|
|
|
|
|
|
|
$self->$init_method(); |
259
|
|
|
|
|
|
|
return $self; |
260
|
|
|
|
|
|
|
}, |
261
|
|
|
|
|
|
|
'instance_with_methods' => q{ |
262
|
|
|
|
|
|
|
$self = ref ($self) ? $self : _EMPTY_NEW_INSTANCE_; |
263
|
|
|
|
|
|
|
_CALL_METHODS_FROM_HASH_ |
264
|
|
|
|
|
|
|
return $self; |
265
|
|
|
|
|
|
|
}, |
266
|
|
|
|
|
|
|
'copy_with_values' => q{ |
267
|
|
|
|
|
|
|
@_ = ( %$self, @_ ); |
268
|
|
|
|
|
|
|
$self = _EMPTY_NEW_INSTANCE_; |
269
|
|
|
|
|
|
|
_SET_VALUES_FROM_HASH_ |
270
|
|
|
|
|
|
|
return $self; |
271
|
|
|
|
|
|
|
}, |
272
|
|
|
|
|
|
|
'copy_with_methods' => q{ |
273
|
|
|
|
|
|
|
@_ = ( %$self, @_ ); |
274
|
|
|
|
|
|
|
$self = _EMPTY_NEW_INSTANCE_; |
275
|
|
|
|
|
|
|
_CALL_METHODS_FROM_HASH_ |
276
|
|
|
|
|
|
|
return $self; |
277
|
|
|
|
|
|
|
}, |
278
|
|
|
|
|
|
|
'copy_instance_with_values' => q{ |
279
|
|
|
|
|
|
|
$self = bless { ( ref $self ? %$self : () ) }, _SELF_CLASS_; |
280
|
|
|
|
|
|
|
_SET_VALUES_FROM_HASH_ |
281
|
|
|
|
|
|
|
return $self; |
282
|
|
|
|
|
|
|
}, |
283
|
|
|
|
|
|
|
'copy_instance_with_methods' => q{ |
284
|
|
|
|
|
|
|
$self = bless { ref $self ? %$self : () }, _SELF_CLASS_; |
285
|
|
|
|
|
|
|
_CALL_METHODS_FROM_HASH_ |
286
|
|
|
|
|
|
|
return $self; |
287
|
|
|
|
|
|
|
}, |
288
|
|
|
|
|
|
|
}, |
289
|
|
|
|
|
|
|
} |
290
|
|
|
|
|
|
|
} |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
######################################################################## |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
=head2 scalar Accessor |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
A generic scalar-value accessor meta-method which serves as an |
297
|
|
|
|
|
|
|
abstraction for basic "get_set" methods and numerous related |
298
|
|
|
|
|
|
|
interfaces |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
use Class::MakeMethods -MakerClass => "...", |
301
|
|
|
|
|
|
|
scalar => [ 'foo', 'bar' ]; |
302
|
|
|
|
|
|
|
... |
303
|
|
|
|
|
|
|
$self->foo( 'my new foo value' ); |
304
|
|
|
|
|
|
|
print $self->foo(); |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
(Note that while you can use the scalar methods to store references to |
307
|
|
|
|
|
|
|
various data structures, there are other meta-methods defined below that |
308
|
|
|
|
|
|
|
may be more useful for managing references to arrays, hashes, and objects.) |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
B: The following calling interfaces are available. |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
=over 4 |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
=item get_set (default) |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
Provides get_set method for I<*>. |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
Example: Create method foo, which sets the value of 'foo' for this |
319
|
|
|
|
|
|
|
instance if an argument is passed in, and then returns the value |
320
|
|
|
|
|
|
|
whether or not it's been changed: |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
use Class::MakeMethods -MakerClass => "...", |
323
|
|
|
|
|
|
|
scalar => [ 'foo' ]; |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
=item get_protected_set |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
Provides an get_set accessor for I<*> that croaks if a new value |
328
|
|
|
|
|
|
|
is passed in from a package that is not a subclass of the declaring |
329
|
|
|
|
|
|
|
one. |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
=item get_private_set |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
Provides an get_set accessor for I<*> that croaks if a new value |
334
|
|
|
|
|
|
|
is passed in from a package other than the declaring one. |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
=item read_only |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
Provides an accessor for I<*> that does not modify its value. (Its |
339
|
|
|
|
|
|
|
initial value would have to be set by some other means.) |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
=item eiffel |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
Provides get behavior as I<*>, and set behavior as set_I<*>. |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
Example: Create methods bar which returns the value of 'bar' for |
346
|
|
|
|
|
|
|
this instance (takes no arguments), and set_bar, which sets the |
347
|
|
|
|
|
|
|
value of 'bar' (no return): |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
use Class::MakeMethods -MakerClass => "...", |
350
|
|
|
|
|
|
|
scalar => [ --eiffel => 'bar' ]; |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
=item java |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
Provides get behavior as getI<*>, and set behavior as setI<*>. |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
Example: Create methods getBaz which returns the value of 'Baz' |
357
|
|
|
|
|
|
|
for this instance (takes no arguments), and setBaz, which sets the |
358
|
|
|
|
|
|
|
value for this instance (no return): |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
use Class::MakeMethods -MakerClass => "...", |
361
|
|
|
|
|
|
|
scalar => [ --java => 'Baz' ]; |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
=item init_and_get |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
Creates methods which cache their results in a hash key. |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
Provides the get_init behavior for I<*>, and an delete behavior for clear_I<*>. |
369
|
|
|
|
|
|
|
Specifies default value for init_method parameter of init_I<*>. |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
=item with_clear |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
Provides get_set behavior for I<*>, and a clear_I<*> method. |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
=back |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
B: The following types of accessor methods are available. |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
=over 4 |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
=item get_set |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
If no argument is provided, returns the value of the current instance. The value defaults to undef. |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
If an argument is provided, it is stored as the value of the current |
388
|
|
|
|
|
|
|
instance (even if the argument is undef), and that value is returned. |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
Also available as get_protected_set and get_private_set, which are |
391
|
|
|
|
|
|
|
available for public read-only access, but have access control |
392
|
|
|
|
|
|
|
limitations. |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
=item get |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
Returns the value from the current instance. |
397
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
=item set |
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
Sets the value for the current instance. If called with no arguments, |
401
|
|
|
|
|
|
|
the value is set to undef. Does not return a value. |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
=item clear |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
Sets value to undef. |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
=item get_set_chain |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
Like get_set, but if called with an argument, returns the object it was called on. This allows a series of mutators to be called as follows: |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
package MyObject; |
412
|
|
|
|
|
|
|
use Class::MakeMethods ( |
413
|
|
|
|
|
|
|
'Template::Hash:scalar --get_set_chain' => 'foo bar baz' |
414
|
|
|
|
|
|
|
); |
415
|
|
|
|
|
|
|
... |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
my $obj = MyObject->new->foo('Foozle'); |
418
|
|
|
|
|
|
|
$obj->bar("none")->baz("Brazil"); |
419
|
|
|
|
|
|
|
print $obj->foo, $obj->bar, $obj->baz; |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
=item get_set_prev |
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
Like get_set, but if called with an argument, returns the previous value before it was changed to the new one. |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
=item get_init |
426
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
If the value is currently undefined, calls the init_method. Returns the value. |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
=back |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
B: The following parameters are supported: |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
=over 4 |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
=item init_method |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
The name of a method to be called to initialize this meta-method. |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
Only used by the get_init behavior. |
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
=back |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
=cut |
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
sub scalar { |
446
|
|
|
|
|
|
|
{ |
447
|
59
|
|
|
59
|
1
|
2860
|
'-import' => { 'Template::Generic:generic' => '*' }, |
448
|
|
|
|
|
|
|
'interface' => { |
449
|
|
|
|
|
|
|
default => 'get_set', |
450
|
|
|
|
|
|
|
get_set => { '*'=>'get_set' }, |
451
|
|
|
|
|
|
|
noclear => { '*'=>'get_set' }, |
452
|
|
|
|
|
|
|
with_clear => { '*'=>'get_set', 'clear_*'=>'clear' }, |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
read_only => { '*'=>'get' }, |
455
|
|
|
|
|
|
|
get_private_set => 'get_private_set', |
456
|
|
|
|
|
|
|
get_protected_set => 'get_protected_set', |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
eiffel => { '*'=>'get', 'set_*'=>'set_return' }, |
459
|
|
|
|
|
|
|
java => { 'get*'=>'get', 'set*'=>'set_return' }, |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
init_and_get => { '*'=>'get_init', -params=>{ init_method=>'init_*' } }, |
462
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
}, |
464
|
|
|
|
|
|
|
'behavior' => { |
465
|
|
|
|
|
|
|
'get' => q{ _GET_VALUE_ }, |
466
|
|
|
|
|
|
|
'set' => q{ _SET_VALUE_{ shift() } }, |
467
|
|
|
|
|
|
|
'set_return' => q{ _BEHAVIOR_{set}; return }, |
468
|
|
|
|
|
|
|
'clear' => q{ _SET_VALUE_{ undef } }, |
469
|
|
|
|
|
|
|
'defined' => q{ defined _VALUE_ }, |
470
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
'get_set' => q { |
472
|
|
|
|
|
|
|
if ( scalar @_ ) { |
473
|
|
|
|
|
|
|
_BEHAVIOR_{set} |
474
|
|
|
|
|
|
|
} else { |
475
|
|
|
|
|
|
|
_BEHAVIOR_{get} |
476
|
|
|
|
|
|
|
} |
477
|
|
|
|
|
|
|
}, |
478
|
|
|
|
|
|
|
'get_set_chain' => q { |
479
|
|
|
|
|
|
|
if ( scalar @_ ) { |
480
|
|
|
|
|
|
|
_BEHAVIOR_{set}; |
481
|
|
|
|
|
|
|
return _SELF_ |
482
|
|
|
|
|
|
|
} else { |
483
|
|
|
|
|
|
|
_BEHAVIOR_{get} |
484
|
|
|
|
|
|
|
} |
485
|
|
|
|
|
|
|
}, |
486
|
|
|
|
|
|
|
'get_set_prev' => q { |
487
|
|
|
|
|
|
|
my $value = _BEHAVIOR_{get}; |
488
|
|
|
|
|
|
|
if ( scalar @_ ) { |
489
|
|
|
|
|
|
|
_BEHAVIOR_{set}; |
490
|
|
|
|
|
|
|
} |
491
|
|
|
|
|
|
|
return $value; |
492
|
|
|
|
|
|
|
}, |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
'get_private_set' => q{ |
495
|
|
|
|
|
|
|
if ( scalar @_ ) { |
496
|
|
|
|
|
|
|
_PRIVATE_SET_VALUE_{ shift() } |
497
|
|
|
|
|
|
|
} else { |
498
|
|
|
|
|
|
|
_BEHAVIOR_{get} |
499
|
|
|
|
|
|
|
} |
500
|
|
|
|
|
|
|
}, |
501
|
|
|
|
|
|
|
'get_protected_set' => q{ |
502
|
|
|
|
|
|
|
if ( scalar @_ ) { |
503
|
|
|
|
|
|
|
_PROTECTED_SET_VALUE_{ shift() } |
504
|
|
|
|
|
|
|
} else { |
505
|
|
|
|
|
|
|
_BEHAVIOR_{get} |
506
|
|
|
|
|
|
|
} |
507
|
|
|
|
|
|
|
}, |
508
|
|
|
|
|
|
|
'get_init' => q{ |
509
|
|
|
|
|
|
|
if ( ! defined _VALUE_ ) { |
510
|
|
|
|
|
|
|
my $init_method = _ATTR_REQUIRED_{'init_method'}; |
511
|
|
|
|
|
|
|
_SET_VALUE_{ _SELF_->$init_method( @_ ) }; |
512
|
|
|
|
|
|
|
} else { |
513
|
|
|
|
|
|
|
_BEHAVIOR_{get} |
514
|
|
|
|
|
|
|
} |
515
|
|
|
|
|
|
|
}, |
516
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
}, |
518
|
|
|
|
|
|
|
'params' => { |
519
|
|
|
|
|
|
|
new_method => 'new' |
520
|
|
|
|
|
|
|
}, |
521
|
|
|
|
|
|
|
} |
522
|
|
|
|
|
|
|
} |
523
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
######################################################################## |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
=head2 string Accessor |
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
A generic scalar-value accessor meta-method which serves as an |
529
|
|
|
|
|
|
|
abstraction for basic "get_set" methods and numerous related |
530
|
|
|
|
|
|
|
interfaces |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
use Class::MakeMethods -MakerClass => "...", |
533
|
|
|
|
|
|
|
string => [ 'foo', 'bar' ]; |
534
|
|
|
|
|
|
|
... |
535
|
|
|
|
|
|
|
$self->foo( 'my new foo value' ); |
536
|
|
|
|
|
|
|
print $self->foo(); |
537
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
This meta-method extends the scalar meta-method, and supports the same interfaces and parameters. |
539
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
However, it generally treats values as strings, and can not be used to store references. |
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
B: In addition to those provided by C, the following calling interfaces are available. |
543
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
=over 4 |
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
=item -get_concat |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
Provides the get_concat behavior for I<*>, and a clear_I<*> method. |
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
Example: |
551
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
use Class::MakeMethods |
553
|
|
|
|
|
|
|
get_concat => { name => 'words', join => ", " }; |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
$obj->words('foo'); |
556
|
|
|
|
|
|
|
$obj->words('bar'); |
557
|
|
|
|
|
|
|
$obj->words() eq 'foo, bar'; |
558
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
=back |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
B: In addition to those provided by C, the following types of accessor methods are available. |
562
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
=over 4 |
564
|
|
|
|
|
|
|
|
565
|
|
|
|
|
|
|
=item concat |
566
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
Concatenates the argument value with the existing value. |
568
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
=item get_concat |
570
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
Like get_set except sets do not clear out the original value, but instead |
572
|
|
|
|
|
|
|
concatenate the new value to the existing one. |
573
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
=back |
575
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
B: In addition to those provided by C, the following parameters are supported. |
577
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
=over 4 |
579
|
|
|
|
|
|
|
|
580
|
|
|
|
|
|
|
=item join |
581
|
|
|
|
|
|
|
|
582
|
|
|
|
|
|
|
If the join parameter is defined, each time the get_concat behavior |
583
|
|
|
|
|
|
|
is invoked, it will glue its argument onto any existing value with |
584
|
|
|
|
|
|
|
the join string as the separator. The join field is applied I |
585
|
|
|
|
|
|
|
values, not prior to the first or after the last. Defaults to undefined |
586
|
|
|
|
|
|
|
|
587
|
|
|
|
|
|
|
=back |
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
=cut |
590
|
|
|
|
|
|
|
|
591
|
|
|
|
|
|
|
sub string { |
592
|
|
|
|
|
|
|
{ |
593
|
3
|
|
|
3
|
1
|
95
|
'-import' => { 'Template::Generic:scalar' => '*' }, |
594
|
|
|
|
|
|
|
'interface' => { |
595
|
|
|
|
|
|
|
get_concat => { '*'=>'get_concat', 'clear_*'=>'clear', |
596
|
|
|
|
|
|
|
-params=>{ 'join' => '' }, }, |
597
|
|
|
|
|
|
|
}, |
598
|
|
|
|
|
|
|
'params' => { |
599
|
|
|
|
|
|
|
'return_value_undefined' => '', |
600
|
|
|
|
|
|
|
}, |
601
|
|
|
|
|
|
|
'behavior' => { |
602
|
|
|
|
|
|
|
'get' => q{ |
603
|
|
|
|
|
|
|
if ( defined( my $value = _GET_VALUE_) ) { |
604
|
|
|
|
|
|
|
_GET_VALUE_; |
605
|
|
|
|
|
|
|
} else { |
606
|
|
|
|
|
|
|
_STATIC_ATTR_{return_value_undefined}; |
607
|
|
|
|
|
|
|
} |
608
|
|
|
|
|
|
|
}, |
609
|
|
|
|
|
|
|
'set' => q{ |
610
|
|
|
|
|
|
|
my $new_value = shift(); |
611
|
|
|
|
|
|
|
_SET_VALUE_{ "$new_value" }; |
612
|
|
|
|
|
|
|
}, |
613
|
|
|
|
|
|
|
'concat' => q{ |
614
|
|
|
|
|
|
|
my $new_value = shift(); |
615
|
|
|
|
|
|
|
if ( defined( my $value = _GET_VALUE_) ) { |
616
|
|
|
|
|
|
|
_SET_VALUE_{join( _STATIC_ATTR_{join}, $value, $new_value)}; |
617
|
|
|
|
|
|
|
} else { |
618
|
|
|
|
|
|
|
_SET_VALUE_{ "$new_value" }; |
619
|
|
|
|
|
|
|
} |
620
|
|
|
|
|
|
|
}, |
621
|
|
|
|
|
|
|
'get_concat' => q{ |
622
|
|
|
|
|
|
|
if ( scalar @_ ) { |
623
|
|
|
|
|
|
|
_BEHAVIOR_{concat} |
624
|
|
|
|
|
|
|
} else { |
625
|
|
|
|
|
|
|
_BEHAVIOR_{get} |
626
|
|
|
|
|
|
|
} |
627
|
|
|
|
|
|
|
}, |
628
|
|
|
|
|
|
|
}, |
629
|
|
|
|
|
|
|
} |
630
|
|
|
|
|
|
|
} |
631
|
|
|
|
|
|
|
|
632
|
|
|
|
|
|
|
######################################################################## |
633
|
|
|
|
|
|
|
|
634
|
|
|
|
|
|
|
=head2 string_index |
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
string_index => [ qw / foo bar baz / ] |
637
|
|
|
|
|
|
|
|
638
|
|
|
|
|
|
|
Creates string accessor methods, like string above, but also |
639
|
|
|
|
|
|
|
maintains a static hash index in which each object is stored under |
640
|
|
|
|
|
|
|
the value of the field when the slot is set. |
641
|
|
|
|
|
|
|
|
642
|
|
|
|
|
|
|
This is a unique index, so only one object can have a given key. |
643
|
|
|
|
|
|
|
If an object has a slot set to a value which another object is |
644
|
|
|
|
|
|
|
already set to the object currently set to that value has that slot |
645
|
|
|
|
|
|
|
set to undef and the new object will be put into the hash under |
646
|
|
|
|
|
|
|
that value. |
647
|
|
|
|
|
|
|
|
648
|
|
|
|
|
|
|
Objects with undefined values are not stored in the index. |
649
|
|
|
|
|
|
|
|
650
|
|
|
|
|
|
|
Note that to free items from memory, you must clear these values! |
651
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
B: |
653
|
|
|
|
|
|
|
|
654
|
|
|
|
|
|
|
=over 4 |
655
|
|
|
|
|
|
|
|
656
|
|
|
|
|
|
|
=item * |
657
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
The method find_x is defined which if called with any arguments |
659
|
|
|
|
|
|
|
returns a list of the objects stored under those values in the |
660
|
|
|
|
|
|
|
hash. Called with no arguments, it returns a reference to the hash. |
661
|
|
|
|
|
|
|
|
662
|
|
|
|
|
|
|
=back |
663
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
B: |
665
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
=over 4 |
667
|
|
|
|
|
|
|
|
668
|
|
|
|
|
|
|
=item * |
669
|
|
|
|
|
|
|
|
670
|
|
|
|
|
|
|
find_or_new |
671
|
|
|
|
|
|
|
|
672
|
|
|
|
|
|
|
'string_index -find_or_new' => [ qw / foo bar baz / ] |
673
|
|
|
|
|
|
|
|
674
|
|
|
|
|
|
|
Just like string_index except the find_x method is defined to call the new |
675
|
|
|
|
|
|
|
method to create an object if there is no object already stored under |
676
|
|
|
|
|
|
|
any of the keys you give as arguments. |
677
|
|
|
|
|
|
|
|
678
|
|
|
|
|
|
|
=back |
679
|
|
|
|
|
|
|
|
680
|
|
|
|
|
|
|
=cut |
681
|
|
|
|
|
|
|
|
682
|
|
|
|
|
|
|
sub string_index { |
683
|
|
|
|
|
|
|
( { |
684
|
|
|
|
|
|
|
'-import' => { 'Template::Generic:generic' => '*' }, |
685
|
|
|
|
|
|
|
'params' => { |
686
|
|
|
|
|
|
|
'new_method' => 'new', |
687
|
|
|
|
|
|
|
}, |
688
|
|
|
|
|
|
|
'interface' => { |
689
|
|
|
|
|
|
|
default => { '*'=>'get_set', 'clear_*'=>'clear', 'find_*'=>'find' }, |
690
|
|
|
|
|
|
|
find_or_new=>{'*'=>'get_set', 'clear_*'=>'clear', 'find_*'=>'find_or_new'} |
691
|
|
|
|
|
|
|
}, |
692
|
|
|
|
|
|
|
'code_expr' => { |
693
|
|
|
|
|
|
|
_REMOVE_FROM_INDEX_ => q{ |
694
|
|
|
|
|
|
|
if (defined ( my $old_v = _GET_VALUE_ ) ) { |
695
|
|
|
|
|
|
|
delete _ATTR_{'index'}{ $old_v }; |
696
|
|
|
|
|
|
|
} |
697
|
|
|
|
|
|
|
}, |
698
|
|
|
|
|
|
|
_ADD_TO_INDEX_ => q{ |
699
|
|
|
|
|
|
|
if (defined ( my $new_value = _GET_VALUE_ ) ) { |
700
|
|
|
|
|
|
|
if ( my $old_item = _ATTR_{'index'}{$new_value} ) { |
701
|
|
|
|
|
|
|
# There's already an object stored under that value so we |
702
|
|
|
|
|
|
|
# need to unset it's value. |
703
|
|
|
|
|
|
|
# And maybe issue a warning? Or croak? |
704
|
|
|
|
|
|
|
my $m_name = _ATTR_{'name'}; |
705
|
|
|
|
|
|
|
$old_item->$m_name( undef ); |
706
|
|
|
|
|
|
|
} |
707
|
|
|
|
|
|
|
|
708
|
|
|
|
|
|
|
# Put ourself in the index under that value |
709
|
|
|
|
|
|
|
_ATTR_{'index'}{$new_value} = _SELF_; |
710
|
|
|
|
|
|
|
} |
711
|
|
|
|
|
|
|
}, |
712
|
|
|
|
|
|
|
_INDEX_HASH_ => '_ATTR_{index}', |
713
|
|
|
|
|
|
|
}, |
714
|
|
|
|
|
|
|
'behavior' => { |
715
|
|
|
|
|
|
|
'-init' => [ sub { |
716
|
12
|
|
|
12
|
|
25
|
my $m_info = $_[0]; |
717
|
12
|
50
|
|
|
|
188
|
defined $m_info->{'index'} or $m_info->{'index'} = {}; |
718
|
12
|
|
|
|
|
78
|
return; |
719
|
4
|
|
|
4
|
1
|
145
|
} ], |
720
|
|
|
|
|
|
|
'get' => q{ |
721
|
|
|
|
|
|
|
return _GET_VALUE_; |
722
|
|
|
|
|
|
|
}, |
723
|
|
|
|
|
|
|
'set' => q{ |
724
|
|
|
|
|
|
|
my $new_value = shift; |
725
|
|
|
|
|
|
|
|
726
|
|
|
|
|
|
|
_REMOVE_FROM_INDEX_ |
727
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
# Set our value to new |
729
|
|
|
|
|
|
|
_SET_VALUE_{ $new_value }; |
730
|
|
|
|
|
|
|
|
731
|
|
|
|
|
|
|
_ADD_TO_INDEX_ |
732
|
|
|
|
|
|
|
}, |
733
|
|
|
|
|
|
|
'get_set' => q{ |
734
|
|
|
|
|
|
|
if ( scalar @_ ) { |
735
|
|
|
|
|
|
|
_BEHAVIOR_{set} |
736
|
|
|
|
|
|
|
} else { |
737
|
|
|
|
|
|
|
_BEHAVIOR_{get} |
738
|
|
|
|
|
|
|
} |
739
|
|
|
|
|
|
|
}, |
740
|
|
|
|
|
|
|
'clear' => q{ |
741
|
|
|
|
|
|
|
_REMOVE_FROM_INDEX_ |
742
|
|
|
|
|
|
|
_SET_VALUE_{ undef }; |
743
|
|
|
|
|
|
|
}, |
744
|
|
|
|
|
|
|
'find' => q{ |
745
|
|
|
|
|
|
|
if ( scalar @_ ) { |
746
|
|
|
|
|
|
|
return @{ _ATTR_{'index'} }{ @_ }; |
747
|
|
|
|
|
|
|
} else { |
748
|
|
|
|
|
|
|
return _INDEX_HASH_ |
749
|
|
|
|
|
|
|
} |
750
|
|
|
|
|
|
|
}, |
751
|
|
|
|
|
|
|
'find_or_new' => q{ |
752
|
|
|
|
|
|
|
if ( scalar @_ ) { |
753
|
|
|
|
|
|
|
my $class = _SELF_CLASS_; |
754
|
|
|
|
|
|
|
my $new_method = _ATTR_REQUIRED_{'new_method'}; |
755
|
|
|
|
|
|
|
my $m_name = _ATTR_{'name'}; |
756
|
|
|
|
|
|
|
foreach (@_) { |
757
|
|
|
|
|
|
|
next if defined _ATTR_{'index'}{$_}; |
758
|
|
|
|
|
|
|
# create new instance and set its value; it'll add itself to index |
759
|
|
|
|
|
|
|
$class->$new_method()->$m_name($_); |
760
|
|
|
|
|
|
|
} |
761
|
|
|
|
|
|
|
return @{ _ATTR_{'index'} }{ @_ }; |
762
|
|
|
|
|
|
|
} else { |
763
|
|
|
|
|
|
|
return _INDEX_HASH_ |
764
|
|
|
|
|
|
|
} |
765
|
|
|
|
|
|
|
}, |
766
|
|
|
|
|
|
|
}, |
767
|
|
|
|
|
|
|
} ) |
768
|
|
|
|
|
|
|
} |
769
|
|
|
|
|
|
|
|
770
|
|
|
|
|
|
|
######################################################################## |
771
|
|
|
|
|
|
|
|
772
|
|
|
|
|
|
|
=head2 number Accessor |
773
|
|
|
|
|
|
|
|
774
|
|
|
|
|
|
|
A generic scalar-value accessor meta-method which serves as an |
775
|
|
|
|
|
|
|
abstraction for basic "get_set" methods and numerous related |
776
|
|
|
|
|
|
|
interfaces |
777
|
|
|
|
|
|
|
|
778
|
|
|
|
|
|
|
use Class::MakeMethods -MakerClass => "...", |
779
|
|
|
|
|
|
|
string => [ 'foo', 'bar' ]; |
780
|
|
|
|
|
|
|
... |
781
|
|
|
|
|
|
|
$self->foo( 23 ); |
782
|
|
|
|
|
|
|
print $self->foo(); |
783
|
|
|
|
|
|
|
|
784
|
|
|
|
|
|
|
This meta-method extends the scalar meta-method, and supports the same interfaces and parameters. |
785
|
|
|
|
|
|
|
|
786
|
|
|
|
|
|
|
However, it generally treats values as numbers, and can not be used to store strings or references. |
787
|
|
|
|
|
|
|
|
788
|
|
|
|
|
|
|
B: In addition to those provided by C, the following calling interfaces are available. |
789
|
|
|
|
|
|
|
|
790
|
|
|
|
|
|
|
=over 4 |
791
|
|
|
|
|
|
|
|
792
|
|
|
|
|
|
|
=item -counter |
793
|
|
|
|
|
|
|
|
794
|
|
|
|
|
|
|
Provides the numeric get_set behavior for I<*>, and numeric I<*>_incr and I<*>_reset methods. |
795
|
|
|
|
|
|
|
|
796
|
|
|
|
|
|
|
=back |
797
|
|
|
|
|
|
|
|
798
|
|
|
|
|
|
|
B: In addition to those provided by C, the following types of accessor methods are available. |
799
|
|
|
|
|
|
|
|
800
|
|
|
|
|
|
|
=over 4 |
801
|
|
|
|
|
|
|
|
802
|
|
|
|
|
|
|
=item get_set |
803
|
|
|
|
|
|
|
|
804
|
|
|
|
|
|
|
The get_set behavior is similar to the default scalar behavior except that empty values are treated as zero. |
805
|
|
|
|
|
|
|
|
806
|
|
|
|
|
|
|
=item increment |
807
|
|
|
|
|
|
|
|
808
|
|
|
|
|
|
|
If no argument is provided, increments the I value by 1. |
809
|
|
|
|
|
|
|
If an argument is provided, the value is incremented by that amount. |
810
|
|
|
|
|
|
|
Returns the increased value. |
811
|
|
|
|
|
|
|
|
812
|
|
|
|
|
|
|
=item clear |
813
|
|
|
|
|
|
|
|
814
|
|
|
|
|
|
|
Sets the value to zero. |
815
|
|
|
|
|
|
|
|
816
|
|
|
|
|
|
|
=back |
817
|
|
|
|
|
|
|
|
818
|
|
|
|
|
|
|
=cut |
819
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
sub number { |
821
|
|
|
|
|
|
|
{ |
822
|
7
|
|
|
7
|
1
|
117
|
'-import' => { 'Template::Generic:scalar' => '*' }, |
823
|
|
|
|
|
|
|
'interface' => { |
824
|
|
|
|
|
|
|
counter => { '*'=>'get_set', '*_incr'=>'incr', '*_reset'=>'clear' }, |
825
|
|
|
|
|
|
|
}, |
826
|
|
|
|
|
|
|
'params' => { |
827
|
|
|
|
|
|
|
'return_value_undefined' => 0, |
828
|
|
|
|
|
|
|
}, |
829
|
|
|
|
|
|
|
'behavior' => { |
830
|
|
|
|
|
|
|
'get_set' => q{ |
831
|
|
|
|
|
|
|
if ( scalar @_ ) { |
832
|
|
|
|
|
|
|
local $_ = shift; |
833
|
|
|
|
|
|
|
if ( defined $_ ) { |
834
|
|
|
|
|
|
|
croak "Can't set _STATIC_ATTR_{name} to non-numeric value '$_'" |
835
|
|
|
|
|
|
|
if ( /[^\+\-\,\d\.e]/ ); |
836
|
|
|
|
|
|
|
s/\,//g; |
837
|
|
|
|
|
|
|
} |
838
|
|
|
|
|
|
|
_SET_VALUE_{ $_ } |
839
|
|
|
|
|
|
|
} |
840
|
|
|
|
|
|
|
defined( _GET_VALUE_ ) ? _GET_VALUE_ |
841
|
|
|
|
|
|
|
: _STATIC_ATTR_{return_value_undefined} |
842
|
|
|
|
|
|
|
}, |
843
|
|
|
|
|
|
|
'incr' => q{ |
844
|
|
|
|
|
|
|
_VALUE_ ||= 0; |
845
|
|
|
|
|
|
|
_VALUE_ += ( scalar @_ ? shift : 1 ) |
846
|
|
|
|
|
|
|
}, |
847
|
|
|
|
|
|
|
'decr' => q{ |
848
|
|
|
|
|
|
|
_VALUE_ ||= 0; |
849
|
|
|
|
|
|
|
_VALUE_ -= ( scalar @_ ? shift : 1 ) |
850
|
|
|
|
|
|
|
}, |
851
|
|
|
|
|
|
|
}, |
852
|
|
|
|
|
|
|
} |
853
|
|
|
|
|
|
|
} |
854
|
|
|
|
|
|
|
|
855
|
|
|
|
|
|
|
######################################################################## |
856
|
|
|
|
|
|
|
|
857
|
|
|
|
|
|
|
=head2 boolean Accessor |
858
|
|
|
|
|
|
|
|
859
|
|
|
|
|
|
|
A generic scalar-value accessor meta-method which serves as an abstraction for basic "get_set" methods and numerous related interfaces |
860
|
|
|
|
|
|
|
|
861
|
|
|
|
|
|
|
use Class::MakeMethods -MakerClass => "...", |
862
|
|
|
|
|
|
|
string => [ 'foo', 'bar' ]; |
863
|
|
|
|
|
|
|
... |
864
|
|
|
|
|
|
|
$self->foo( 1 ); |
865
|
|
|
|
|
|
|
print $self->foo(); |
866
|
|
|
|
|
|
|
$self->clear_foo; |
867
|
|
|
|
|
|
|
|
868
|
|
|
|
|
|
|
This meta-method extends the scalar meta-method, and supports the |
869
|
|
|
|
|
|
|
same interfaces and parameters. However, it generally treats values |
870
|
|
|
|
|
|
|
as true-or-false flags, and can not be used to store strings, |
871
|
|
|
|
|
|
|
numbers, or references. |
872
|
|
|
|
|
|
|
|
873
|
|
|
|
|
|
|
B: |
874
|
|
|
|
|
|
|
|
875
|
|
|
|
|
|
|
=over 4 |
876
|
|
|
|
|
|
|
|
877
|
|
|
|
|
|
|
=item flag_set_clear (default) |
878
|
|
|
|
|
|
|
|
879
|
|
|
|
|
|
|
Provides the get_set behavior for I<*>, and set_I<*> and clear_I<*> methods to set the value to true or false. |
880
|
|
|
|
|
|
|
|
881
|
|
|
|
|
|
|
=back |
882
|
|
|
|
|
|
|
|
883
|
|
|
|
|
|
|
B: In addition to those provided by C, the following types of accessor methods are available. |
884
|
|
|
|
|
|
|
|
885
|
|
|
|
|
|
|
=over 4 |
886
|
|
|
|
|
|
|
|
887
|
|
|
|
|
|
|
=item get_set |
888
|
|
|
|
|
|
|
|
889
|
|
|
|
|
|
|
The get_set behavior is similar to the get_set scalar behavior |
890
|
|
|
|
|
|
|
except that empty or false values are treated as zero, and true |
891
|
|
|
|
|
|
|
values are treated as zero. |
892
|
|
|
|
|
|
|
|
893
|
|
|
|
|
|
|
=item set_true |
894
|
|
|
|
|
|
|
|
895
|
|
|
|
|
|
|
Sets the value to one. |
896
|
|
|
|
|
|
|
|
897
|
|
|
|
|
|
|
=item set_false |
898
|
|
|
|
|
|
|
|
899
|
|
|
|
|
|
|
Sets the value to zero. |
900
|
|
|
|
|
|
|
=back |
901
|
|
|
|
|
|
|
|
902
|
|
|
|
|
|
|
=cut |
903
|
|
|
|
|
|
|
|
904
|
|
|
|
|
|
|
sub boolean { |
905
|
|
|
|
|
|
|
{ |
906
|
3
|
|
|
3
|
1
|
80
|
'-import' => { 'Template::Generic:scalar' => '*' }, |
907
|
|
|
|
|
|
|
'interface' => { |
908
|
|
|
|
|
|
|
default => {'*'=>'get_set', 'clear_*'=>'set_false', |
909
|
|
|
|
|
|
|
'set_*'=>'set_true'}, |
910
|
|
|
|
|
|
|
flag_set_clear => {'*'=>'get_set', 'clear_*'=>'set_false', |
911
|
|
|
|
|
|
|
'set_*'=>'set_true'}, |
912
|
|
|
|
|
|
|
}, |
913
|
|
|
|
|
|
|
'behavior' => { |
914
|
|
|
|
|
|
|
'get' => q{ _GET_VALUE_ || 0 }, |
915
|
|
|
|
|
|
|
'set' => q{ |
916
|
|
|
|
|
|
|
if ( shift ) { |
917
|
|
|
|
|
|
|
_BEHAVIOR_{set_true} |
918
|
|
|
|
|
|
|
} else { |
919
|
|
|
|
|
|
|
_BEHAVIOR_{set_false} |
920
|
|
|
|
|
|
|
} |
921
|
|
|
|
|
|
|
}, |
922
|
|
|
|
|
|
|
'set_true' => q{ _SET_VALUE_{ 1 } }, |
923
|
|
|
|
|
|
|
'set_false' => q{ _SET_VALUE_{ 0 } }, |
924
|
|
|
|
|
|
|
'set_value' => q{ |
925
|
|
|
|
|
|
|
_SET_VALUE_{ scalar @_ ? shift : 1 } |
926
|
|
|
|
|
|
|
}, |
927
|
|
|
|
|
|
|
}, |
928
|
|
|
|
|
|
|
} |
929
|
|
|
|
|
|
|
} |
930
|
|
|
|
|
|
|
|
931
|
|
|
|
|
|
|
######################################################################## |
932
|
|
|
|
|
|
|
|
933
|
|
|
|
|
|
|
=head2 bits Accessor |
934
|
|
|
|
|
|
|
|
935
|
|
|
|
|
|
|
A generic accessor for bit-field values. |
936
|
|
|
|
|
|
|
|
937
|
|
|
|
|
|
|
The difference between 'Template::Generic:bits' and |
938
|
|
|
|
|
|
|
'Template::Generic:boolean' is that all flags created with this |
939
|
|
|
|
|
|
|
meta-method are stored in a single vector for space efficiency. |
940
|
|
|
|
|
|
|
|
941
|
|
|
|
|
|
|
B: The following calling interfaces are available. |
942
|
|
|
|
|
|
|
|
943
|
|
|
|
|
|
|
=over 4 |
944
|
|
|
|
|
|
|
|
945
|
|
|
|
|
|
|
=item default |
946
|
|
|
|
|
|
|
|
947
|
|
|
|
|
|
|
Provides get_set behavior for I<*>, a set_I<*> method which sets |
948
|
|
|
|
|
|
|
the value to true and a clear_I<*> method which sets the value to |
949
|
|
|
|
|
|
|
false. |
950
|
|
|
|
|
|
|
|
951
|
|
|
|
|
|
|
Also defines methods named bits, bit_fields, and bit_dump with the |
952
|
|
|
|
|
|
|
behaviors below. These methods are shared across all of the boolean |
953
|
|
|
|
|
|
|
meta-methods defined by a single class. |
954
|
|
|
|
|
|
|
|
955
|
|
|
|
|
|
|
=item class_methods |
956
|
|
|
|
|
|
|
|
957
|
|
|
|
|
|
|
. |
958
|
|
|
|
|
|
|
|
959
|
|
|
|
|
|
|
=back |
960
|
|
|
|
|
|
|
|
961
|
|
|
|
|
|
|
B: The following types of bit-level accessor methods are available. |
962
|
|
|
|
|
|
|
|
963
|
|
|
|
|
|
|
=over 4 |
964
|
|
|
|
|
|
|
|
965
|
|
|
|
|
|
|
=item get_set |
966
|
|
|
|
|
|
|
|
967
|
|
|
|
|
|
|
Returns the value of the named flag. If called with an argument, it first |
968
|
|
|
|
|
|
|
sets the named flag to the truth-value of the argument. |
969
|
|
|
|
|
|
|
|
970
|
|
|
|
|
|
|
=item set_true |
971
|
|
|
|
|
|
|
|
972
|
|
|
|
|
|
|
Sets the value to true. |
973
|
|
|
|
|
|
|
|
974
|
|
|
|
|
|
|
=item set_false |
975
|
|
|
|
|
|
|
|
976
|
|
|
|
|
|
|
Sets the value to false. |
977
|
|
|
|
|
|
|
|
978
|
|
|
|
|
|
|
=back |
979
|
|
|
|
|
|
|
|
980
|
|
|
|
|
|
|
B: The following types of methods manipulate the overall vector value. |
981
|
|
|
|
|
|
|
|
982
|
|
|
|
|
|
|
=over 4 |
983
|
|
|
|
|
|
|
|
984
|
|
|
|
|
|
|
=item bits |
985
|
|
|
|
|
|
|
|
986
|
|
|
|
|
|
|
Returns the vector containing all of the bit fields (remember however |
987
|
|
|
|
|
|
|
that a vector containing all 0 bits is still true). |
988
|
|
|
|
|
|
|
|
989
|
|
|
|
|
|
|
=item bit_dump |
990
|
|
|
|
|
|
|
|
991
|
|
|
|
|
|
|
Returns a hash of the flag-name/flag-value pairs. |
992
|
|
|
|
|
|
|
|
993
|
|
|
|
|
|
|
=item bits_size |
994
|
|
|
|
|
|
|
|
995
|
|
|
|
|
|
|
Returns the number of bits that can fit into the current vector. |
996
|
|
|
|
|
|
|
|
997
|
|
|
|
|
|
|
=item bits_complement |
998
|
|
|
|
|
|
|
|
999
|
|
|
|
|
|
|
Returns the twos-complement of the vector. |
1000
|
|
|
|
|
|
|
|
1001
|
|
|
|
|
|
|
=item bit_pos_get |
1002
|
|
|
|
|
|
|
|
1003
|
|
|
|
|
|
|
Takes a single argument and returns the value of the bit stored in that position. |
1004
|
|
|
|
|
|
|
|
1005
|
|
|
|
|
|
|
=item bit_pos_set |
1006
|
|
|
|
|
|
|
|
1007
|
|
|
|
|
|
|
Takes two arguments and sets the bit stored in the position of the first argument to the value of the second argument. |
1008
|
|
|
|
|
|
|
|
1009
|
|
|
|
|
|
|
=back |
1010
|
|
|
|
|
|
|
|
1011
|
|
|
|
|
|
|
B: The following types of class methods are available. |
1012
|
|
|
|
|
|
|
|
1013
|
|
|
|
|
|
|
=over 4 |
1014
|
|
|
|
|
|
|
|
1015
|
|
|
|
|
|
|
=item bit_names |
1016
|
|
|
|
|
|
|
|
1017
|
|
|
|
|
|
|
Returns a list of all the flags by name. |
1018
|
|
|
|
|
|
|
|
1019
|
|
|
|
|
|
|
=back |
1020
|
|
|
|
|
|
|
|
1021
|
|
|
|
|
|
|
=cut |
1022
|
|
|
|
|
|
|
|
1023
|
|
|
|
|
|
|
sub bits { |
1024
|
|
|
|
|
|
|
{ |
1025
|
|
|
|
|
|
|
'-import' => { |
1026
|
|
|
|
|
|
|
# 'Template::Generic:generic' => '*', |
1027
|
|
|
|
|
|
|
}, |
1028
|
|
|
|
|
|
|
'interface' => { |
1029
|
|
|
|
|
|
|
default => { |
1030
|
|
|
|
|
|
|
'*'=>'get_set', 'set_*'=>'set_true', 'clear_*'=>'set_false', |
1031
|
|
|
|
|
|
|
'bit_fields'=>'bit_names', 'bit_string'=>'bit_string', |
1032
|
|
|
|
|
|
|
'bit_list'=>'bit_list', 'bit_hash'=>'bit_hash', |
1033
|
|
|
|
|
|
|
}, |
1034
|
|
|
|
|
|
|
class_methods => { |
1035
|
|
|
|
|
|
|
'bit_fields'=>'bit_names', 'bit_string'=>'bit_string', |
1036
|
|
|
|
|
|
|
'bit_list'=>'bit_list', 'bit_hash'=>'bit_hash', |
1037
|
|
|
|
|
|
|
}, |
1038
|
|
|
|
|
|
|
}, |
1039
|
|
|
|
|
|
|
'code_expr' => { |
1040
|
|
|
|
|
|
|
'_VEC_POS_VALUE_{}' => 'vec(_VALUE_, *, 1)', |
1041
|
|
|
|
|
|
|
_VEC_VALUE_ => '_VEC_POS_VALUE_{ _ATTR_{bfp} }', |
1042
|
|
|
|
|
|
|
_CLASS_INFO_ => '$Class::MakeMethods::Template::Hash::bits{_STATIC_ATTR_{target_class}}', |
1043
|
|
|
|
|
|
|
}, |
1044
|
|
|
|
|
|
|
'modifier' => { |
1045
|
|
|
|
|
|
|
'-all' => [ q{ |
1046
|
|
|
|
|
|
|
defined _VALUE_ or _VALUE_ = ""; |
1047
|
|
|
|
|
|
|
* |
1048
|
|
|
|
|
|
|
} ], |
1049
|
|
|
|
|
|
|
}, |
1050
|
|
|
|
|
|
|
'behavior' => { |
1051
|
|
|
|
|
|
|
'-init' => sub { |
1052
|
20
|
|
|
20
|
|
29
|
my $m_info = $_[0]; |
1053
|
|
|
|
|
|
|
|
1054
|
20
|
|
66
|
|
|
113
|
$m_info->{bfp} ||= do { |
1055
|
20
|
|
100
|
|
|
82
|
my $array = ( $Class::MakeMethods::Template::Hash::bits{$m_info->{target_class}} ||= [] ); |
1056
|
20
|
|
|
|
|
26
|
my $idx; |
1057
|
20
|
|
|
|
|
49
|
foreach ( 0..$#$array ) { |
1058
|
32
|
50
|
|
|
|
106
|
if ( $array->[$_] eq $m_info->{'name'} ) { $idx = $_; last } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
1059
|
|
|
|
|
|
|
} |
1060
|
20
|
50
|
|
|
|
46
|
unless ( $idx ) { |
1061
|
20
|
|
|
|
|
55
|
push @$array, $m_info->{'name'}; |
1062
|
20
|
|
|
|
|
33
|
$idx = $#$array; |
1063
|
|
|
|
|
|
|
} |
1064
|
20
|
|
|
|
|
62
|
$idx; |
1065
|
|
|
|
|
|
|
}; |
1066
|
|
|
|
|
|
|
|
1067
|
20
|
|
|
|
|
58
|
return; |
1068
|
|
|
|
|
|
|
}, |
1069
|
4
|
|
|
4
|
1
|
166
|
'bit_names' => q{ |
1070
|
|
|
|
|
|
|
@{ _CLASS_INFO_ }; |
1071
|
|
|
|
|
|
|
}, |
1072
|
|
|
|
|
|
|
'bit_string' => q{ |
1073
|
|
|
|
|
|
|
if ( @_ ) { |
1074
|
|
|
|
|
|
|
_SET_VALUE_{ shift @_ }; |
1075
|
|
|
|
|
|
|
} else { |
1076
|
|
|
|
|
|
|
_VALUE_; |
1077
|
|
|
|
|
|
|
} |
1078
|
|
|
|
|
|
|
}, |
1079
|
|
|
|
|
|
|
'bits_size' => q{ |
1080
|
|
|
|
|
|
|
8 * length( _VALUE_ ); |
1081
|
|
|
|
|
|
|
}, |
1082
|
|
|
|
|
|
|
'bits_complement' => q{ |
1083
|
|
|
|
|
|
|
~ _VALUE_; |
1084
|
|
|
|
|
|
|
}, |
1085
|
|
|
|
|
|
|
'bit_hash' => q{ |
1086
|
|
|
|
|
|
|
my @bits = @{ _CLASS_INFO_ }; |
1087
|
|
|
|
|
|
|
if ( @_ ) { |
1088
|
|
|
|
|
|
|
my %bits = @_; |
1089
|
|
|
|
|
|
|
_SET_VALUE_{ pack 'b*', join '', map { $_ ? 1 : 0 } @bits{ @bits } }; |
1090
|
|
|
|
|
|
|
return @_; |
1091
|
|
|
|
|
|
|
} else { |
1092
|
|
|
|
|
|
|
map { $bits[$_], vec(_VALUE_, $_, 1) } 0 .. $#bits |
1093
|
|
|
|
|
|
|
} |
1094
|
|
|
|
|
|
|
}, |
1095
|
|
|
|
|
|
|
'bit_list' => q{ |
1096
|
|
|
|
|
|
|
if ( @_ ) { |
1097
|
|
|
|
|
|
|
_SET_VALUE_{ pack 'b*', join( '', map { $_ ? 1 : 0 } @_ ) }; |
1098
|
|
|
|
|
|
|
return map { $_ ? 1 : 0 } @_; |
1099
|
|
|
|
|
|
|
} else { |
1100
|
|
|
|
|
|
|
split //, unpack "b*", _VALUE_; |
1101
|
|
|
|
|
|
|
} |
1102
|
|
|
|
|
|
|
}, |
1103
|
|
|
|
|
|
|
'bit_pos_get' => q{ |
1104
|
|
|
|
|
|
|
vec(_VALUE_, $_[0], 1) |
1105
|
|
|
|
|
|
|
}, |
1106
|
|
|
|
|
|
|
'bit_pos_set' => q{ |
1107
|
|
|
|
|
|
|
vec(_VALUE_, $_[0], 1) = ( $_[1] ? 1 : 0 ) |
1108
|
|
|
|
|
|
|
}, |
1109
|
|
|
|
|
|
|
|
1110
|
|
|
|
|
|
|
'get_set' => q{ |
1111
|
|
|
|
|
|
|
if ( @_ ) { |
1112
|
|
|
|
|
|
|
_VEC_VALUE_ = ( $_[0] ? 1 : 0 ); |
1113
|
|
|
|
|
|
|
} else { |
1114
|
|
|
|
|
|
|
_VEC_VALUE_; |
1115
|
|
|
|
|
|
|
} |
1116
|
|
|
|
|
|
|
}, |
1117
|
|
|
|
|
|
|
'get' => q{ |
1118
|
|
|
|
|
|
|
_VEC_VALUE_; |
1119
|
|
|
|
|
|
|
}, |
1120
|
|
|
|
|
|
|
'set' => q{ |
1121
|
|
|
|
|
|
|
_VEC_VALUE_ = ( $_[0] ? 1 : 0 ); |
1122
|
|
|
|
|
|
|
}, |
1123
|
|
|
|
|
|
|
'set_true' => q{ |
1124
|
|
|
|
|
|
|
_VEC_VALUE_ = 1; |
1125
|
|
|
|
|
|
|
}, |
1126
|
|
|
|
|
|
|
'set_false' => q{ |
1127
|
|
|
|
|
|
|
_VEC_VALUE_ = 0; |
1128
|
|
|
|
|
|
|
}, |
1129
|
|
|
|
|
|
|
|
1130
|
|
|
|
|
|
|
}, |
1131
|
|
|
|
|
|
|
} |
1132
|
|
|
|
|
|
|
} |
1133
|
|
|
|
|
|
|
|
1134
|
|
|
|
|
|
|
|
1135
|
|
|
|
|
|
|
######################################################################## |
1136
|
|
|
|
|
|
|
|
1137
|
|
|
|
|
|
|
=head2 array Accessor |
1138
|
|
|
|
|
|
|
|
1139
|
|
|
|
|
|
|
Creates accessor methods for manipulating arrays of values. |
1140
|
|
|
|
|
|
|
|
1141
|
|
|
|
|
|
|
B: The following calling interfaces are available. |
1142
|
|
|
|
|
|
|
|
1143
|
|
|
|
|
|
|
=over 4 |
1144
|
|
|
|
|
|
|
|
1145
|
|
|
|
|
|
|
=item default |
1146
|
|
|
|
|
|
|
|
1147
|
|
|
|
|
|
|
Provides get_set behavior for I<*>, and I_I<*> methods for the non-get behaviors below. |
1148
|
|
|
|
|
|
|
|
1149
|
|
|
|
|
|
|
=item minimal |
1150
|
|
|
|
|
|
|
|
1151
|
|
|
|
|
|
|
Provides get_set behavior for I<*>, and I<*>_I methods for clear behavior. |
1152
|
|
|
|
|
|
|
|
1153
|
|
|
|
|
|
|
=item get_set_items |
1154
|
|
|
|
|
|
|
|
1155
|
|
|
|
|
|
|
Provides the get_set_items for I<*>. |
1156
|
|
|
|
|
|
|
|
1157
|
|
|
|
|
|
|
=item x_verb |
1158
|
|
|
|
|
|
|
|
1159
|
|
|
|
|
|
|
Provides get_push behavior for I<*>, and I<*>_I methods for the non-get behaviors below. |
1160
|
|
|
|
|
|
|
|
1161
|
|
|
|
|
|
|
=item get_set_ref |
1162
|
|
|
|
|
|
|
|
1163
|
|
|
|
|
|
|
Provides the get_set_ref for I<*>. |
1164
|
|
|
|
|
|
|
|
1165
|
|
|
|
|
|
|
=item get_set_ref_help |
1166
|
|
|
|
|
|
|
|
1167
|
|
|
|
|
|
|
Provides the get_set_ref for I<*>, and I_I<*> methods for the non-get behaviors below. |
1168
|
|
|
|
|
|
|
|
1169
|
|
|
|
|
|
|
=back |
1170
|
|
|
|
|
|
|
|
1171
|
|
|
|
|
|
|
B: The following types of accessor methods are available. |
1172
|
|
|
|
|
|
|
|
1173
|
|
|
|
|
|
|
=over 4 |
1174
|
|
|
|
|
|
|
|
1175
|
|
|
|
|
|
|
=item get_set_items |
1176
|
|
|
|
|
|
|
|
1177
|
|
|
|
|
|
|
Called with no arguments returns a reference to the array stored in the slot. |
1178
|
|
|
|
|
|
|
|
1179
|
|
|
|
|
|
|
Called with one simple scalar argument it treats the argument as an index |
1180
|
|
|
|
|
|
|
and returns the value stored under that index. |
1181
|
|
|
|
|
|
|
|
1182
|
|
|
|
|
|
|
Called with more than one argument, treats them as a series of index/value |
1183
|
|
|
|
|
|
|
pairs and adds them to the array. |
1184
|
|
|
|
|
|
|
|
1185
|
|
|
|
|
|
|
=item get_push |
1186
|
|
|
|
|
|
|
|
1187
|
|
|
|
|
|
|
If arguments are passed, these values are pushed on to the list; if a single array ref is passed, its values are used as the arguments. |
1188
|
|
|
|
|
|
|
|
1189
|
|
|
|
|
|
|
This method returns the list of values stored in the slot. In an array |
1190
|
|
|
|
|
|
|
context it returns them as an array and in a scalar context as a |
1191
|
|
|
|
|
|
|
reference to the array. |
1192
|
|
|
|
|
|
|
|
1193
|
|
|
|
|
|
|
=item get_set_ref |
1194
|
|
|
|
|
|
|
|
1195
|
|
|
|
|
|
|
If arguments are passed, these values are placed on the list, replacing the current contents; if a single array ref is passed, its values are used as the arguments. |
1196
|
|
|
|
|
|
|
|
1197
|
|
|
|
|
|
|
This method returns the list of values stored in the slot. In an array |
1198
|
|
|
|
|
|
|
context it returns them as an array and in a scalar context as a |
1199
|
|
|
|
|
|
|
reference to the array. |
1200
|
|
|
|
|
|
|
|
1201
|
|
|
|
|
|
|
=item get_set |
1202
|
|
|
|
|
|
|
|
1203
|
|
|
|
|
|
|
If arguments are passed, these values are placed on the list, replacing the current contents. |
1204
|
|
|
|
|
|
|
|
1205
|
|
|
|
|
|
|
This method returns the list of values stored in the slot. In an array |
1206
|
|
|
|
|
|
|
context it returns them as an array and in a scalar context as a |
1207
|
|
|
|
|
|
|
reference to the array. |
1208
|
|
|
|
|
|
|
|
1209
|
|
|
|
|
|
|
|
1210
|
|
|
|
|
|
|
=item push |
1211
|
|
|
|
|
|
|
|
1212
|
|
|
|
|
|
|
Append items to tail. |
1213
|
|
|
|
|
|
|
|
1214
|
|
|
|
|
|
|
=item pop |
1215
|
|
|
|
|
|
|
|
1216
|
|
|
|
|
|
|
Remove an item from the tail. |
1217
|
|
|
|
|
|
|
|
1218
|
|
|
|
|
|
|
=item shift |
1219
|
|
|
|
|
|
|
|
1220
|
|
|
|
|
|
|
Remove an item from the front. |
1221
|
|
|
|
|
|
|
|
1222
|
|
|
|
|
|
|
=item unshift |
1223
|
|
|
|
|
|
|
|
1224
|
|
|
|
|
|
|
Prepend items to front. |
1225
|
|
|
|
|
|
|
|
1226
|
|
|
|
|
|
|
=item splice |
1227
|
|
|
|
|
|
|
|
1228
|
|
|
|
|
|
|
Remove or replace items. |
1229
|
|
|
|
|
|
|
|
1230
|
|
|
|
|
|
|
=item clear |
1231
|
|
|
|
|
|
|
|
1232
|
|
|
|
|
|
|
Remove all items. |
1233
|
|
|
|
|
|
|
|
1234
|
|
|
|
|
|
|
=item count |
1235
|
|
|
|
|
|
|
|
1236
|
|
|
|
|
|
|
Returns the number of item in the list. |
1237
|
|
|
|
|
|
|
|
1238
|
|
|
|
|
|
|
=back |
1239
|
|
|
|
|
|
|
|
1240
|
|
|
|
|
|
|
=cut |
1241
|
|
|
|
|
|
|
|
1242
|
|
|
|
|
|
|
sub array { |
1243
|
|
|
|
|
|
|
{ |
1244
|
13
|
|
|
13
|
1
|
1140
|
'-import' => { 'Template::Generic:generic' => '*' }, |
1245
|
|
|
|
|
|
|
'interface' => { |
1246
|
|
|
|
|
|
|
default => { |
1247
|
|
|
|
|
|
|
'*'=>'get_set', |
1248
|
|
|
|
|
|
|
map( ($_.'_*' => $_ ), qw( pop push unshift shift splice clear count )), |
1249
|
|
|
|
|
|
|
map( ('*_'.$_ => $_ ), qw( ref index ) ), |
1250
|
|
|
|
|
|
|
}, |
1251
|
|
|
|
|
|
|
minimal => { '*'=>'get_set', '*_clear'=>'clear' }, |
1252
|
|
|
|
|
|
|
get_set_items => { '*'=>'get_set_items' }, |
1253
|
|
|
|
|
|
|
x_verb => { |
1254
|
|
|
|
|
|
|
'*'=>'get_set', |
1255
|
|
|
|
|
|
|
map( ('*_'.$_ => $_ ), qw(pop push unshift shift splice clear count ref index )), |
1256
|
|
|
|
|
|
|
}, |
1257
|
|
|
|
|
|
|
get_set_ref => { '*'=>'get_set_ref' }, |
1258
|
|
|
|
|
|
|
get_set_ref_help => { '*'=>'get_set_ref', '-base'=>'default' }, |
1259
|
|
|
|
|
|
|
}, |
1260
|
|
|
|
|
|
|
'modifier' => { |
1261
|
|
|
|
|
|
|
'-all' => [ q{ _ENSURE_REF_VALUE_; * } ], |
1262
|
|
|
|
|
|
|
}, |
1263
|
|
|
|
|
|
|
'code_expr' => { |
1264
|
|
|
|
|
|
|
'_ENSURE_REF_VALUE_' => q{ _REF_VALUE_ ||= []; }, |
1265
|
|
|
|
|
|
|
}, |
1266
|
|
|
|
|
|
|
'behavior' => { |
1267
|
|
|
|
|
|
|
'get_set' => q{ |
1268
|
|
|
|
|
|
|
@{_REF_VALUE_} = @_ if ( scalar @_ ); |
1269
|
|
|
|
|
|
|
return wantarray ? @{_GET_VALUE_} : _REF_VALUE_; |
1270
|
|
|
|
|
|
|
}, |
1271
|
|
|
|
|
|
|
'get_set_ref' => q{ |
1272
|
|
|
|
|
|
|
@{_REF_VALUE_} = ( ( scalar(@_) == 1 and ref($_[0]) eq 'ARRAY' ) ? @{$_[0]} : @_ ) if ( scalar @_ ); |
1273
|
|
|
|
|
|
|
return wantarray ? @{_GET_VALUE_} : _REF_VALUE_; |
1274
|
|
|
|
|
|
|
}, |
1275
|
|
|
|
|
|
|
'get_push' => q{ |
1276
|
|
|
|
|
|
|
push @{_REF_VALUE_}, map { ref $_ eq 'ARRAY' ? @$_ : ($_) } @_; |
1277
|
|
|
|
|
|
|
return wantarray ? @{_GET_VALUE_} : _REF_VALUE_; |
1278
|
|
|
|
|
|
|
}, |
1279
|
|
|
|
|
|
|
'ref' => q{ _REF_VALUE_ }, |
1280
|
|
|
|
|
|
|
'get' => q{ return wantarray ? @{_GET_VALUE_} : _REF_VALUE_ }, |
1281
|
|
|
|
|
|
|
'set' => q{ @{_REF_VALUE_} = @_ }, |
1282
|
|
|
|
|
|
|
'pop' => q{ pop @{_REF_VALUE_} }, |
1283
|
|
|
|
|
|
|
'push' => q{ push @{_REF_VALUE_}, @_ }, |
1284
|
|
|
|
|
|
|
'shift' => q{ shift @{_REF_VALUE_} }, |
1285
|
|
|
|
|
|
|
'unshift' => q{ unshift @{_REF_VALUE_}, @_ }, |
1286
|
|
|
|
|
|
|
'slice' => q{ _GET_VALUE_->[ @_ ] }, |
1287
|
|
|
|
|
|
|
'splice' => q{ splice @{_REF_VALUE_}, shift, shift, @_ }, |
1288
|
|
|
|
|
|
|
'count' => q{ scalar @{_GET_VALUE_} }, |
1289
|
|
|
|
|
|
|
'clear' => q{ @{ _REF_VALUE_ } = () }, |
1290
|
|
|
|
|
|
|
'index' => q{ |
1291
|
|
|
|
|
|
|
my $list = _REF_VALUE_; |
1292
|
|
|
|
|
|
|
( scalar(@_) == 1 ) ? $list->[shift] |
1293
|
|
|
|
|
|
|
: wantarray ? (map $list->[$_], @_) : [map $list->[$_], @_] |
1294
|
|
|
|
|
|
|
}, |
1295
|
|
|
|
|
|
|
'get_set_items' => q{ |
1296
|
|
|
|
|
|
|
if ( scalar @_ == 0 ) { |
1297
|
|
|
|
|
|
|
return _REF_VALUE_; |
1298
|
|
|
|
|
|
|
} elsif ( scalar @_ == 1 ) { |
1299
|
|
|
|
|
|
|
return _GET_VALUE_->[ shift() ]; |
1300
|
|
|
|
|
|
|
} else { |
1301
|
|
|
|
|
|
|
_BEHAVIOR_{set_items} |
1302
|
|
|
|
|
|
|
} |
1303
|
|
|
|
|
|
|
}, |
1304
|
|
|
|
|
|
|
'set_items' => q{ |
1305
|
|
|
|
|
|
|
! (@_ % 2) or croak "Odd number of items in assigment to _STATIC_ATTR_{name}"; |
1306
|
|
|
|
|
|
|
while ( scalar @_ ) { |
1307
|
|
|
|
|
|
|
my ($index, $value) = splice @_, 0, 2; |
1308
|
|
|
|
|
|
|
_REF_VALUE_->[ $index ] = $value; |
1309
|
|
|
|
|
|
|
} |
1310
|
|
|
|
|
|
|
return _REF_VALUE_; |
1311
|
|
|
|
|
|
|
}, |
1312
|
|
|
|
|
|
|
} |
1313
|
|
|
|
|
|
|
} |
1314
|
|
|
|
|
|
|
} |
1315
|
|
|
|
|
|
|
|
1316
|
|
|
|
|
|
|
######################################################################## |
1317
|
|
|
|
|
|
|
|
1318
|
|
|
|
|
|
|
=head2 hash Accessor |
1319
|
|
|
|
|
|
|
|
1320
|
|
|
|
|
|
|
Creates accessor methods for manipulating hashes of key-value pairs. |
1321
|
|
|
|
|
|
|
|
1322
|
|
|
|
|
|
|
B: The following calling interfaces are available. |
1323
|
|
|
|
|
|
|
|
1324
|
|
|
|
|
|
|
=over 4 |
1325
|
|
|
|
|
|
|
|
1326
|
|
|
|
|
|
|
=item default |
1327
|
|
|
|
|
|
|
|
1328
|
|
|
|
|
|
|
Provides get_set behavior for I<*>, and I<*>_I methods for most of the other behaviors below. |
1329
|
|
|
|
|
|
|
|
1330
|
|
|
|
|
|
|
=item get_set_items |
1331
|
|
|
|
|
|
|
|
1332
|
|
|
|
|
|
|
Provides the get_set_items for I<*>. |
1333
|
|
|
|
|
|
|
|
1334
|
|
|
|
|
|
|
=back |
1335
|
|
|
|
|
|
|
|
1336
|
|
|
|
|
|
|
B: The following types of accessor methods are available. |
1337
|
|
|
|
|
|
|
|
1338
|
|
|
|
|
|
|
=over 4 |
1339
|
|
|
|
|
|
|
|
1340
|
|
|
|
|
|
|
=item get_set_items |
1341
|
|
|
|
|
|
|
|
1342
|
|
|
|
|
|
|
Called with no arguments returns a reference to the hash stored. |
1343
|
|
|
|
|
|
|
|
1344
|
|
|
|
|
|
|
Called with one simple scalar argument it treats the argument as a key |
1345
|
|
|
|
|
|
|
and returns the value stored under that key. |
1346
|
|
|
|
|
|
|
|
1347
|
|
|
|
|
|
|
Called with more than one argument, treats them as a series of key/value |
1348
|
|
|
|
|
|
|
pairs and adds them to the hash. |
1349
|
|
|
|
|
|
|
|
1350
|
|
|
|
|
|
|
=item get_push |
1351
|
|
|
|
|
|
|
|
1352
|
|
|
|
|
|
|
Called with no arguments returns the hash stored, as a hash |
1353
|
|
|
|
|
|
|
in a list context or as a reference in a scalar context. |
1354
|
|
|
|
|
|
|
|
1355
|
|
|
|
|
|
|
Called with one simple scalar argument it treats the argument as a key |
1356
|
|
|
|
|
|
|
and returns the value stored under that key. |
1357
|
|
|
|
|
|
|
|
1358
|
|
|
|
|
|
|
Called with one array reference argument, the array elements |
1359
|
|
|
|
|
|
|
are considered to be be keys of the hash. x returns the list of values |
1360
|
|
|
|
|
|
|
stored under those keys (also known as a I.) |
1361
|
|
|
|
|
|
|
|
1362
|
|
|
|
|
|
|
Called with one hash reference argument, the keys and values of the |
1363
|
|
|
|
|
|
|
hash are added to the hash. |
1364
|
|
|
|
|
|
|
|
1365
|
|
|
|
|
|
|
Called with more than one argument, treats them as a series of key/value |
1366
|
|
|
|
|
|
|
pairs and adds them to the hash. |
1367
|
|
|
|
|
|
|
|
1368
|
|
|
|
|
|
|
=item get_set |
1369
|
|
|
|
|
|
|
|
1370
|
|
|
|
|
|
|
Like get_push, except if called with more then one argument, empties |
1371
|
|
|
|
|
|
|
the current hash items before adding those arguments to the hash. |
1372
|
|
|
|
|
|
|
|
1373
|
|
|
|
|
|
|
=item push |
1374
|
|
|
|
|
|
|
|
1375
|
|
|
|
|
|
|
Called with one hash reference argument, the keys and values of the |
1376
|
|
|
|
|
|
|
hash are added to the hash. |
1377
|
|
|
|
|
|
|
|
1378
|
|
|
|
|
|
|
Called with more than one argument, treats them as a series of key/value |
1379
|
|
|
|
|
|
|
pairs and adds them to the hash. |
1380
|
|
|
|
|
|
|
|
1381
|
|
|
|
|
|
|
=item keys |
1382
|
|
|
|
|
|
|
|
1383
|
|
|
|
|
|
|
Returns a list of the keys of the hash. |
1384
|
|
|
|
|
|
|
|
1385
|
|
|
|
|
|
|
=item values |
1386
|
|
|
|
|
|
|
|
1387
|
|
|
|
|
|
|
Returns a list of the values in the hash. |
1388
|
|
|
|
|
|
|
|
1389
|
|
|
|
|
|
|
=item tally |
1390
|
|
|
|
|
|
|
|
1391
|
|
|
|
|
|
|
Takes a list of arguments and for each scalar in the list increments the |
1392
|
|
|
|
|
|
|
value stored in the hash and returns a list of the current (after the |
1393
|
|
|
|
|
|
|
increment) values. |
1394
|
|
|
|
|
|
|
|
1395
|
|
|
|
|
|
|
=item exists |
1396
|
|
|
|
|
|
|
|
1397
|
|
|
|
|
|
|
Takes a single key, returns whether that key exists in the hash. |
1398
|
|
|
|
|
|
|
|
1399
|
|
|
|
|
|
|
=item delete |
1400
|
|
|
|
|
|
|
|
1401
|
|
|
|
|
|
|
Takes a list, deletes each key from the hash, and returns the corresponding values. |
1402
|
|
|
|
|
|
|
|
1403
|
|
|
|
|
|
|
=item clear |
1404
|
|
|
|
|
|
|
|
1405
|
|
|
|
|
|
|
Resets hash to empty. |
1406
|
|
|
|
|
|
|
|
1407
|
|
|
|
|
|
|
=back |
1408
|
|
|
|
|
|
|
|
1409
|
|
|
|
|
|
|
=cut |
1410
|
|
|
|
|
|
|
|
1411
|
|
|
|
|
|
|
sub hash { |
1412
|
|
|
|
|
|
|
{ |
1413
|
80
|
|
|
|
|
672
|
'-import' => { 'Template::Generic:generic' => '*' }, |
1414
|
|
|
|
|
|
|
'interface' => { |
1415
|
|
|
|
|
|
|
'default' => { |
1416
|
|
|
|
|
|
|
'*'=>'get_set', |
1417
|
10
|
|
|
10
|
1
|
54
|
map {'*_'.$_ => $_} qw(push set keys values delete exists tally clear), |
1418
|
|
|
|
|
|
|
}, |
1419
|
|
|
|
|
|
|
get_set_items => { '*'=>'get_set_items' }, |
1420
|
|
|
|
|
|
|
}, |
1421
|
|
|
|
|
|
|
'modifier' => { |
1422
|
|
|
|
|
|
|
'-all' => [ q{ _ENSURE_REF_VALUE_; * } ], |
1423
|
|
|
|
|
|
|
}, |
1424
|
|
|
|
|
|
|
'code_expr' => { |
1425
|
|
|
|
|
|
|
'_ENSURE_REF_VALUE_' => q{ _REF_VALUE_ ||= {}; }, |
1426
|
|
|
|
|
|
|
_HASH_GET_ => q{ |
1427
|
|
|
|
|
|
|
( wantarray ? %{_GET_VALUE_} : _REF_VALUE_ ) |
1428
|
|
|
|
|
|
|
}, |
1429
|
|
|
|
|
|
|
_HASH_GET_VALUE_ => q{ |
1430
|
|
|
|
|
|
|
( ref $_[0] eq 'ARRAY' ? @{ _GET_VALUE_ }{ @{ $_[0] } } |
1431
|
|
|
|
|
|
|
: _REF_VALUE_->{ $_[0] } ) |
1432
|
|
|
|
|
|
|
}, |
1433
|
|
|
|
|
|
|
_HASH_SET_ => q{ |
1434
|
|
|
|
|
|
|
! (@_ % 2) or croak "Odd number of items in assigment to _STATIC_ATTR_{name}"; |
1435
|
|
|
|
|
|
|
%{_REF_VALUE_} = @_ |
1436
|
|
|
|
|
|
|
}, |
1437
|
|
|
|
|
|
|
_HASH_PUSH_ => q{ |
1438
|
|
|
|
|
|
|
! (@_ % 2) |
1439
|
|
|
|
|
|
|
or croak "Odd number of items in assigment to _STATIC_ATTR_{name}"; |
1440
|
|
|
|
|
|
|
my $count; |
1441
|
|
|
|
|
|
|
while ( scalar @_ ) { |
1442
|
|
|
|
|
|
|
local $_ = shift; |
1443
|
|
|
|
|
|
|
_REF_VALUE_->{ $_ } = shift(); |
1444
|
|
|
|
|
|
|
++ $count; |
1445
|
|
|
|
|
|
|
} |
1446
|
|
|
|
|
|
|
$count; |
1447
|
|
|
|
|
|
|
}, |
1448
|
|
|
|
|
|
|
}, |
1449
|
|
|
|
|
|
|
'behavior' => { |
1450
|
|
|
|
|
|
|
'get_set' => q { |
1451
|
|
|
|
|
|
|
# If called with no arguments, return hash contents |
1452
|
|
|
|
|
|
|
return _HASH_GET_ if (scalar @_ == 0); |
1453
|
|
|
|
|
|
|
|
1454
|
|
|
|
|
|
|
# If called with a hash ref, act as if contents of hash were passed |
1455
|
|
|
|
|
|
|
# local @_ = %{ $_[0] } if ( scalar @_ == 1 and ref $_[0] eq 'HASH' ); |
1456
|
|
|
|
|
|
|
@_ = %{ $_[0] } if ( scalar @_ == 1 and ref $_[0] eq 'HASH' ); |
1457
|
|
|
|
|
|
|
|
1458
|
|
|
|
|
|
|
# If called with an index, get that value, or a slice for array refs |
1459
|
|
|
|
|
|
|
return _HASH_GET_VALUE_ if (scalar @_ == 1 ); |
1460
|
|
|
|
|
|
|
|
1461
|
|
|
|
|
|
|
# Push on new values and return complete set |
1462
|
|
|
|
|
|
|
_HASH_SET_; |
1463
|
|
|
|
|
|
|
return _HASH_GET_; |
1464
|
|
|
|
|
|
|
}, |
1465
|
|
|
|
|
|
|
|
1466
|
|
|
|
|
|
|
'get_push' => q{ |
1467
|
|
|
|
|
|
|
# If called with no arguments, return hash contents |
1468
|
|
|
|
|
|
|
return _HASH_GET_ if (scalar @_ == 0); |
1469
|
|
|
|
|
|
|
|
1470
|
|
|
|
|
|
|
# If called with a hash ref, act as if contents of hash were passed |
1471
|
|
|
|
|
|
|
# local @_ = %{ $_[0] } if ( scalar @_ == 1 and ref $_[0] eq 'HASH' ); |
1472
|
|
|
|
|
|
|
@_ = %{ $_[0] } if ( scalar @_ == 1 and ref $_[0] eq 'HASH' ); |
1473
|
|
|
|
|
|
|
|
1474
|
|
|
|
|
|
|
# If called with an index, get that value, or a slice for array refs |
1475
|
|
|
|
|
|
|
return _HASH_GET_VALUE_ if (scalar @_ == 1 ); |
1476
|
|
|
|
|
|
|
|
1477
|
|
|
|
|
|
|
# Push on new values and return complete set |
1478
|
|
|
|
|
|
|
_HASH_PUSH_; |
1479
|
|
|
|
|
|
|
return _HASH_GET_; |
1480
|
|
|
|
|
|
|
}, |
1481
|
|
|
|
|
|
|
'get_set_items' => q{ |
1482
|
|
|
|
|
|
|
if ( scalar @_ == 0 ) { |
1483
|
|
|
|
|
|
|
return _REF_VALUE_; |
1484
|
|
|
|
|
|
|
} elsif ( scalar @_ == 1 ) { |
1485
|
|
|
|
|
|
|
return _REF_VALUE_->{ shift() }; |
1486
|
|
|
|
|
|
|
} else { |
1487
|
|
|
|
|
|
|
while ( scalar @_ ) { |
1488
|
|
|
|
|
|
|
my ($index, $value) = splice @_, 0, 2; |
1489
|
|
|
|
|
|
|
_REF_VALUE_->{ $index } = $value; |
1490
|
|
|
|
|
|
|
} |
1491
|
|
|
|
|
|
|
return _REF_VALUE_; |
1492
|
|
|
|
|
|
|
} |
1493
|
|
|
|
|
|
|
}, |
1494
|
|
|
|
|
|
|
'get' => q{ _HASH_GET_ }, |
1495
|
|
|
|
|
|
|
'set' => q{ _HASH_SET_ }, |
1496
|
|
|
|
|
|
|
'push' => q{ |
1497
|
|
|
|
|
|
|
# If called with a hash ref, act as if contents of hash were passed |
1498
|
|
|
|
|
|
|
# local @_ = %{ $_[0] } if ( scalar @_ == 1 and ref $_[0] eq 'HASH' ); |
1499
|
|
|
|
|
|
|
@_ = %{ $_[0] } if ( scalar @_ == 1 and ref $_[0] eq 'HASH' ); |
1500
|
|
|
|
|
|
|
|
1501
|
|
|
|
|
|
|
_HASH_PUSH_ |
1502
|
|
|
|
|
|
|
}, |
1503
|
|
|
|
|
|
|
|
1504
|
|
|
|
|
|
|
'keys' => q{ keys %{_GET_VALUE_} }, |
1505
|
|
|
|
|
|
|
'values' => q{ values %{_GET_VALUE_} }, |
1506
|
|
|
|
|
|
|
'unique_values' => q{ |
1507
|
|
|
|
|
|
|
values %{ { map { $_=>$_ } values %{_GET_VALUE_} } } |
1508
|
|
|
|
|
|
|
}, |
1509
|
|
|
|
|
|
|
'delete' => q{ scalar @_ <= 1 ? delete @{ _REF_VALUE_ }{ $_[0] } |
1510
|
|
|
|
|
|
|
: map { delete @{ _REF_VALUE_ }{ $_ } } (@_) }, |
1511
|
|
|
|
|
|
|
'exists' => q{ |
1512
|
|
|
|
|
|
|
return 0 unless defined _GET_VALUE_; |
1513
|
|
|
|
|
|
|
foreach (@_) { return 0 unless exists ( _REF_VALUE_->{$_} ) } |
1514
|
|
|
|
|
|
|
return 1; |
1515
|
|
|
|
|
|
|
}, |
1516
|
|
|
|
|
|
|
'tally' => q{ map { ++ _REF_VALUE_->{$_} } @_ }, |
1517
|
|
|
|
|
|
|
'clear' => q{ %{ _REF_VALUE_ } = () }, |
1518
|
|
|
|
|
|
|
'ref' => q{ _REF_VALUE_ }, |
1519
|
|
|
|
|
|
|
}, |
1520
|
|
|
|
|
|
|
} |
1521
|
|
|
|
|
|
|
} |
1522
|
|
|
|
|
|
|
|
1523
|
|
|
|
|
|
|
######################################################################## |
1524
|
|
|
|
|
|
|
|
1525
|
|
|
|
|
|
|
=head2 tiedhash Accessor |
1526
|
|
|
|
|
|
|
|
1527
|
|
|
|
|
|
|
A variant of Generic:hash which initializes the hash by tieing it to a caller-specified package. |
1528
|
|
|
|
|
|
|
|
1529
|
|
|
|
|
|
|
See the documentation on C for interfaces and behaviors. |
1530
|
|
|
|
|
|
|
|
1531
|
|
|
|
|
|
|
B: The following parameters I be provided: |
1532
|
|
|
|
|
|
|
|
1533
|
|
|
|
|
|
|
=over 4 |
1534
|
|
|
|
|
|
|
|
1535
|
|
|
|
|
|
|
=item tie |
1536
|
|
|
|
|
|
|
|
1537
|
|
|
|
|
|
|
I. The name of the class to tie to. |
1538
|
|
|
|
|
|
|
Id the required class>. |
1539
|
|
|
|
|
|
|
|
1540
|
|
|
|
|
|
|
=item args |
1541
|
|
|
|
|
|
|
|
1542
|
|
|
|
|
|
|
I. Additional arguments for the tie, as an array ref. |
1543
|
|
|
|
|
|
|
|
1544
|
|
|
|
|
|
|
=back |
1545
|
|
|
|
|
|
|
|
1546
|
|
|
|
|
|
|
Example: |
1547
|
|
|
|
|
|
|
|
1548
|
|
|
|
|
|
|
use Class::MakeMethods |
1549
|
|
|
|
|
|
|
tie_hash => [ hits => { tie => q/Tie::RefHash/, args => [] } ]; |
1550
|
|
|
|
|
|
|
|
1551
|
|
|
|
|
|
|
use Class::MakeMethods |
1552
|
|
|
|
|
|
|
tie_hash => [ [qw(hits errors)] => { tie => q/Tie::RefHash/, args => [] } ]; |
1553
|
|
|
|
|
|
|
|
1554
|
|
|
|
|
|
|
use Class::MakeMethods |
1555
|
|
|
|
|
|
|
tie_hash => [ { name => hits, tie => q/Tie::RefHash/, args => [] } ]; |
1556
|
|
|
|
|
|
|
|
1557
|
|
|
|
|
|
|
=cut |
1558
|
|
|
|
|
|
|
|
1559
|
|
|
|
|
|
|
sub tiedhash { |
1560
|
|
|
|
|
|
|
{ |
1561
|
2
|
|
|
2
|
1
|
20
|
'-import' => { 'Template::Generic:hash' => '*' }, |
1562
|
|
|
|
|
|
|
'modifier' => { |
1563
|
|
|
|
|
|
|
'-all' => [ q{ |
1564
|
|
|
|
|
|
|
if ( ! defined _GET_VALUE_ ) { |
1565
|
|
|
|
|
|
|
%{ _REF_VALUE_ } = (); |
1566
|
|
|
|
|
|
|
tie %{ _REF_VALUE_ }, _ATTR_REQUIRED_{tie}, @{ _ATTR_{args} }; |
1567
|
|
|
|
|
|
|
} |
1568
|
|
|
|
|
|
|
* |
1569
|
|
|
|
|
|
|
} ], |
1570
|
|
|
|
|
|
|
}, |
1571
|
|
|
|
|
|
|
} |
1572
|
|
|
|
|
|
|
} |
1573
|
|
|
|
|
|
|
|
1574
|
|
|
|
|
|
|
######################################################################## |
1575
|
|
|
|
|
|
|
|
1576
|
|
|
|
|
|
|
=head2 hash_of_arrays Accessor |
1577
|
|
|
|
|
|
|
|
1578
|
|
|
|
|
|
|
Creates accessor methods for manipulating hashes of array-refs. |
1579
|
|
|
|
|
|
|
|
1580
|
|
|
|
|
|
|
B: The following calling interfaces are available. |
1581
|
|
|
|
|
|
|
|
1582
|
|
|
|
|
|
|
=over 4 |
1583
|
|
|
|
|
|
|
|
1584
|
|
|
|
|
|
|
=item default |
1585
|
|
|
|
|
|
|
|
1586
|
|
|
|
|
|
|
Provides get behavior for I<*>, and I<*>_I methods for the other behaviors below. |
1587
|
|
|
|
|
|
|
|
1588
|
|
|
|
|
|
|
=back |
1589
|
|
|
|
|
|
|
|
1590
|
|
|
|
|
|
|
B: The following types of accessor methods are available. |
1591
|
|
|
|
|
|
|
|
1592
|
|
|
|
|
|
|
=over 4 |
1593
|
|
|
|
|
|
|
|
1594
|
|
|
|
|
|
|
=item get |
1595
|
|
|
|
|
|
|
|
1596
|
|
|
|
|
|
|
Returns all the values for all the given keys, in order. If no keys are |
1597
|
|
|
|
|
|
|
given, returns all the values (in an unspecified key order). |
1598
|
|
|
|
|
|
|
|
1599
|
|
|
|
|
|
|
The result is returned as an arrayref in scalar context. This arrayref |
1600
|
|
|
|
|
|
|
is I part of the data structure; messing with it will not affect |
1601
|
|
|
|
|
|
|
the contents directly (even if a single key was provided as argument.) |
1602
|
|
|
|
|
|
|
|
1603
|
|
|
|
|
|
|
If any argument is provided which is an arrayref, then the members of |
1604
|
|
|
|
|
|
|
that array are used as keys. Thus, the trivial empty-key case may be |
1605
|
|
|
|
|
|
|
utilized with an argument of []. |
1606
|
|
|
|
|
|
|
|
1607
|
|
|
|
|
|
|
=item keys |
1608
|
|
|
|
|
|
|
|
1609
|
|
|
|
|
|
|
Returns the keys of the hash. As an arrayref in scalar context. |
1610
|
|
|
|
|
|
|
|
1611
|
|
|
|
|
|
|
=item exists |
1612
|
|
|
|
|
|
|
|
1613
|
|
|
|
|
|
|
Takes a list of keys, and returns whether all of the key exists in the hash |
1614
|
|
|
|
|
|
|
(i.e., the C of whether the individual keys exist). |
1615
|
|
|
|
|
|
|
|
1616
|
|
|
|
|
|
|
=item delete |
1617
|
|
|
|
|
|
|
|
1618
|
|
|
|
|
|
|
Takes a list, deletes each key from the hash. |
1619
|
|
|
|
|
|
|
|
1620
|
|
|
|
|
|
|
=item push |
1621
|
|
|
|
|
|
|
|
1622
|
|
|
|
|
|
|
Takes a key, and some values. Pushes the values onto the list denoted |
1623
|
|
|
|
|
|
|
by the key. If the first argument is an arrayref, then each element of |
1624
|
|
|
|
|
|
|
that arrayref is treated as a key and the elements pushed onto each |
1625
|
|
|
|
|
|
|
appropriate list. |
1626
|
|
|
|
|
|
|
|
1627
|
|
|
|
|
|
|
=item pop |
1628
|
|
|
|
|
|
|
|
1629
|
|
|
|
|
|
|
Takes a list of keys, and pops each one. Returns the list of popped |
1630
|
|
|
|
|
|
|
elements. undef is returned in the list for each key that is has an |
1631
|
|
|
|
|
|
|
empty list. |
1632
|
|
|
|
|
|
|
|
1633
|
|
|
|
|
|
|
=item unshift |
1634
|
|
|
|
|
|
|
|
1635
|
|
|
|
|
|
|
Like push, only the from the other end of the lists. |
1636
|
|
|
|
|
|
|
|
1637
|
|
|
|
|
|
|
=item shift |
1638
|
|
|
|
|
|
|
|
1639
|
|
|
|
|
|
|
Like pop, only the from the other end of the lists. |
1640
|
|
|
|
|
|
|
|
1641
|
|
|
|
|
|
|
=item splice |
1642
|
|
|
|
|
|
|
|
1643
|
|
|
|
|
|
|
Takes a key, offset, length, and a values list. Splices the list named |
1644
|
|
|
|
|
|
|
by the key. Anything from the offset argument (inclusive) may be |
1645
|
|
|
|
|
|
|
omitted. See L. |
1646
|
|
|
|
|
|
|
|
1647
|
|
|
|
|
|
|
=item clear |
1648
|
|
|
|
|
|
|
|
1649
|
|
|
|
|
|
|
Takes a list of keys. Resets each named list to empty (but does not |
1650
|
|
|
|
|
|
|
delete the keys.) |
1651
|
|
|
|
|
|
|
|
1652
|
|
|
|
|
|
|
=item count |
1653
|
|
|
|
|
|
|
|
1654
|
|
|
|
|
|
|
Takes a list of keys. Returns the sum of the number of elements for |
1655
|
|
|
|
|
|
|
each named list. |
1656
|
|
|
|
|
|
|
|
1657
|
|
|
|
|
|
|
=item index |
1658
|
|
|
|
|
|
|
|
1659
|
|
|
|
|
|
|
Takes a key, and a list of indices. Returns a list of each item at the |
1660
|
|
|
|
|
|
|
corresponding index in the list of the given key. Uses undef for |
1661
|
|
|
|
|
|
|
indices beyond range. |
1662
|
|
|
|
|
|
|
|
1663
|
|
|
|
|
|
|
=item remove |
1664
|
|
|
|
|
|
|
|
1665
|
|
|
|
|
|
|
Takes a key, and a list of indices. Removes each corresponding item |
1666
|
|
|
|
|
|
|
from the named list. The indices are effectively looked up at the point |
1667
|
|
|
|
|
|
|
of call -- thus removing indices 3, 1 from list (a, b, c, d) will |
1668
|
|
|
|
|
|
|
remove (d) and (b). |
1669
|
|
|
|
|
|
|
|
1670
|
|
|
|
|
|
|
=item sift |
1671
|
|
|
|
|
|
|
|
1672
|
|
|
|
|
|
|
Takes a key, and a set of named arguments, which may be a list or a hash |
1673
|
|
|
|
|
|
|
ref. Removes list members based on a grep-like approach. |
1674
|
|
|
|
|
|
|
|
1675
|
|
|
|
|
|
|
=over 4 |
1676
|
|
|
|
|
|
|
|
1677
|
|
|
|
|
|
|
=item filter |
1678
|
|
|
|
|
|
|
|
1679
|
|
|
|
|
|
|
The filter function used (as a coderef). Is passed two arguments, the |
1680
|
|
|
|
|
|
|
value compared against, and the value in the list that is potential for |
1681
|
|
|
|
|
|
|
grepping out. If returns true, the value is removed. Default is C. |
1682
|
|
|
|
|
|
|
|
1683
|
|
|
|
|
|
|
=item keys |
1684
|
|
|
|
|
|
|
|
1685
|
|
|
|
|
|
|
The list keys to sift through (as an arrayref). Unknown keys are |
1686
|
|
|
|
|
|
|
ignored. Default: all the known keys. |
1687
|
|
|
|
|
|
|
|
1688
|
|
|
|
|
|
|
=item values |
1689
|
|
|
|
|
|
|
|
1690
|
|
|
|
|
|
|
The values to sift out (as an arrayref). Default: C<[undef]> |
1691
|
|
|
|
|
|
|
|
1692
|
|
|
|
|
|
|
=back |
1693
|
|
|
|
|
|
|
|
1694
|
|
|
|
|
|
|
=back |
1695
|
|
|
|
|
|
|
|
1696
|
|
|
|
|
|
|
=cut |
1697
|
|
|
|
|
|
|
|
1698
|
|
|
|
|
|
|
sub hash_of_arrays { |
1699
|
|
|
|
|
|
|
{ |
1700
|
3
|
|
|
3
|
1
|
151
|
'-import' => { 'Template::Generic:hash' => '*' }, |
1701
|
|
|
|
|
|
|
'interface' => { |
1702
|
|
|
|
|
|
|
default => { |
1703
|
|
|
|
|
|
|
'*'=>'get', |
1704
|
|
|
|
|
|
|
map( ('*_'.$_ => $_ ), qw(keys exists delete pop push shift unshift splice clear count index remove sift last set )), |
1705
|
|
|
|
|
|
|
}, |
1706
|
|
|
|
|
|
|
}, |
1707
|
|
|
|
|
|
|
'behavior' => { |
1708
|
|
|
|
|
|
|
'get' => q{ |
1709
|
|
|
|
|
|
|
my @Result; |
1710
|
|
|
|
|
|
|
|
1711
|
|
|
|
|
|
|
if ( ! scalar @_ ) { |
1712
|
|
|
|
|
|
|
@Result = map @$_, values %{_VALUE_}; |
1713
|
|
|
|
|
|
|
} elsif ( scalar @_ == 1 and ref ($_[0]) eq 'ARRAY' ) { |
1714
|
|
|
|
|
|
|
@Result = map @$_, @{_VALUE_}{@{$_[0]}}; |
1715
|
|
|
|
|
|
|
} else { |
1716
|
|
|
|
|
|
|
my @keys = map { ref ($_) eq 'ARRAY' ? @$_ : $_ } |
1717
|
|
|
|
|
|
|
grep exists _VALUE_{$_}, @_; |
1718
|
|
|
|
|
|
|
@Result = map @$_, @{_VALUE_}{@keys}; |
1719
|
|
|
|
|
|
|
} |
1720
|
|
|
|
|
|
|
|
1721
|
|
|
|
|
|
|
return wantarray ? @Result : \@Result; |
1722
|
|
|
|
|
|
|
}, |
1723
|
|
|
|
|
|
|
'pop' => q{ |
1724
|
|
|
|
|
|
|
map { pop @{_VALUE_->{$_}} } @_ |
1725
|
|
|
|
|
|
|
}, |
1726
|
|
|
|
|
|
|
'last' => q{ |
1727
|
|
|
|
|
|
|
map { _VALUE_->{$_}->[-1] } @_ |
1728
|
|
|
|
|
|
|
}, |
1729
|
|
|
|
|
|
|
'push' => q{ |
1730
|
|
|
|
|
|
|
for ( ( ref ($_[0]) eq 'ARRAY' ? @{shift()} : shift() ) ) { |
1731
|
|
|
|
|
|
|
push @{_VALUE_->{$_}}, @_; |
1732
|
|
|
|
|
|
|
} |
1733
|
|
|
|
|
|
|
}, |
1734
|
|
|
|
|
|
|
'shift' => q{ |
1735
|
|
|
|
|
|
|
map { shift @{_VALUE_->{$_}} } @_ |
1736
|
|
|
|
|
|
|
}, |
1737
|
|
|
|
|
|
|
'unshift' => q{ |
1738
|
|
|
|
|
|
|
for ( ( ref ($_[0]) eq 'ARRAY' ? @{shift()} : shift() ) ) { |
1739
|
|
|
|
|
|
|
unshift @{_VALUE_->{$_}}, @_; |
1740
|
|
|
|
|
|
|
} |
1741
|
|
|
|
|
|
|
}, |
1742
|
|
|
|
|
|
|
'splice' => q{ |
1743
|
|
|
|
|
|
|
my $key = shift; |
1744
|
|
|
|
|
|
|
splice @{ _VALUE_->{$key} }, shift, shift, @_; |
1745
|
|
|
|
|
|
|
}, |
1746
|
|
|
|
|
|
|
'clear' => q{ |
1747
|
|
|
|
|
|
|
foreach (@_) { _VALUE_->{$_} = []; } |
1748
|
|
|
|
|
|
|
}, |
1749
|
|
|
|
|
|
|
'count' => q{ |
1750
|
|
|
|
|
|
|
my $Result = 0; |
1751
|
|
|
|
|
|
|
foreach (@_) { |
1752
|
|
|
|
|
|
|
# Avoid autovivifying additional entries. |
1753
|
|
|
|
|
|
|
$Result += exists _VALUE_->{$_} ? scalar @{_VALUE_->{$_}} : 0; |
1754
|
|
|
|
|
|
|
} |
1755
|
|
|
|
|
|
|
return $Result; |
1756
|
|
|
|
|
|
|
}, |
1757
|
|
|
|
|
|
|
'index' => q{ |
1758
|
|
|
|
|
|
|
my $key_r = shift; |
1759
|
|
|
|
|
|
|
|
1760
|
|
|
|
|
|
|
my @Result; |
1761
|
|
|
|
|
|
|
my $key; |
1762
|
|
|
|
|
|
|
foreach $key ( ( ref ($key_r) eq 'ARRAY' ? @$key_r : $key_r ) ) { |
1763
|
|
|
|
|
|
|
my $ary = _VALUE_->{$key}; |
1764
|
|
|
|
|
|
|
for (@_) { |
1765
|
|
|
|
|
|
|
push @Result, ( @{$ary} > $_ ) ? $ary->[$_] : undef; |
1766
|
|
|
|
|
|
|
} |
1767
|
|
|
|
|
|
|
} |
1768
|
|
|
|
|
|
|
return wantarray ? @Result : \@Result; |
1769
|
|
|
|
|
|
|
}, |
1770
|
|
|
|
|
|
|
'set' => q{ |
1771
|
|
|
|
|
|
|
my $key_r = shift; |
1772
|
|
|
|
|
|
|
|
1773
|
|
|
|
|
|
|
croak "_ATTR_{name} expects a key and then index => value pairs.\n" |
1774
|
|
|
|
|
|
|
if @_ % 2; |
1775
|
|
|
|
|
|
|
while ( scalar @_ ) { |
1776
|
|
|
|
|
|
|
my $pos = shift; |
1777
|
|
|
|
|
|
|
_VALUE_->{$key_r}->[ $pos ] = shift(); |
1778
|
|
|
|
|
|
|
} |
1779
|
|
|
|
|
|
|
return; |
1780
|
|
|
|
|
|
|
}, |
1781
|
|
|
|
|
|
|
'remove' => q{ |
1782
|
|
|
|
|
|
|
my $key_r = shift; |
1783
|
|
|
|
|
|
|
|
1784
|
|
|
|
|
|
|
my $key; |
1785
|
|
|
|
|
|
|
foreach $key ( ( ref ($key_r) eq 'ARRAY' ? @$key_r : $key_r ) ) { |
1786
|
|
|
|
|
|
|
my $ary = _VALUE_->{$key}; |
1787
|
|
|
|
|
|
|
foreach ( sort {$b<=>$a} grep $_ < @$ary, @_ ) { |
1788
|
|
|
|
|
|
|
splice (@$ary, $_, 1); |
1789
|
|
|
|
|
|
|
} |
1790
|
|
|
|
|
|
|
} |
1791
|
|
|
|
|
|
|
return; |
1792
|
|
|
|
|
|
|
}, |
1793
|
|
|
|
|
|
|
'sift' => q{ |
1794
|
|
|
|
|
|
|
my %args = ( scalar @_ == 1 and ref $_[0] eq 'HASH' ) ? %{$_[0]} : @_; |
1795
|
|
|
|
|
|
|
my $hash = _VALUE_; |
1796
|
|
|
|
|
|
|
my $filter_sr = $args{'filter'} || sub { $_[0] == $_[1] }; |
1797
|
|
|
|
|
|
|
my $keys_ar = $args{'keys'} || [ keys %$hash ]; |
1798
|
|
|
|
|
|
|
my $values_ar = $args{'values'} || [undef]; |
1799
|
|
|
|
|
|
|
|
1800
|
|
|
|
|
|
|
# This is harder than it looks; reverse means we want to grep out only |
1801
|
|
|
|
|
|
|
# if *none* of the values matches. I guess an evaled block, or closure |
1802
|
|
|
|
|
|
|
# or somesuch is called for. |
1803
|
|
|
|
|
|
|
# my $reverse = $args{'reverse'} || 0; |
1804
|
|
|
|
|
|
|
|
1805
|
|
|
|
|
|
|
my ($key, $i, $value); |
1806
|
|
|
|
|
|
|
KEY: foreach $key (@$keys_ar) { |
1807
|
|
|
|
|
|
|
next KEY unless exists $hash->{$key}; |
1808
|
|
|
|
|
|
|
INDEX: for ($i = $#{$hash->{$key}}; $i >= 0; $i--) { |
1809
|
|
|
|
|
|
|
foreach $value (@$values_ar) { |
1810
|
|
|
|
|
|
|
if ( $filter_sr->($value, $hash->{$key}[$i]) ) { |
1811
|
|
|
|
|
|
|
splice @{$hash->{$key}}, $i, 1; |
1812
|
|
|
|
|
|
|
next INDEX; |
1813
|
|
|
|
|
|
|
} |
1814
|
|
|
|
|
|
|
} |
1815
|
|
|
|
|
|
|
} |
1816
|
|
|
|
|
|
|
} |
1817
|
|
|
|
|
|
|
return; |
1818
|
|
|
|
|
|
|
}, |
1819
|
|
|
|
|
|
|
}, |
1820
|
|
|
|
|
|
|
} |
1821
|
|
|
|
|
|
|
} |
1822
|
|
|
|
|
|
|
|
1823
|
|
|
|
|
|
|
######################################################################## |
1824
|
|
|
|
|
|
|
|
1825
|
|
|
|
|
|
|
=head2 object Accessor |
1826
|
|
|
|
|
|
|
|
1827
|
|
|
|
|
|
|
Creates accessor methods for manipulating references to objects. |
1828
|
|
|
|
|
|
|
|
1829
|
|
|
|
|
|
|
In addition to creating a method to get and set the object reference, |
1830
|
|
|
|
|
|
|
the meta-method can also define forwarded methods that automatically |
1831
|
|
|
|
|
|
|
pass calls onto the object stored in that slot; see the description of the 'delegate' parameter below. |
1832
|
|
|
|
|
|
|
|
1833
|
|
|
|
|
|
|
B: The following calling interfaces are available. |
1834
|
|
|
|
|
|
|
|
1835
|
|
|
|
|
|
|
=over 4 |
1836
|
|
|
|
|
|
|
|
1837
|
|
|
|
|
|
|
=item default |
1838
|
|
|
|
|
|
|
|
1839
|
|
|
|
|
|
|
Provides get_set behavior for I<*>, clear behavior for 'delete_*', |
1840
|
|
|
|
|
|
|
and forwarding methods for any values in the method's 'delegate' |
1841
|
|
|
|
|
|
|
or 'soft_delegate' parameters. |
1842
|
|
|
|
|
|
|
|
1843
|
|
|
|
|
|
|
=item get_and_set |
1844
|
|
|
|
|
|
|
|
1845
|
|
|
|
|
|
|
Provides named get method, set_I and clear_I methods. |
1846
|
|
|
|
|
|
|
|
1847
|
|
|
|
|
|
|
=item get_init_and_set |
1848
|
|
|
|
|
|
|
|
1849
|
|
|
|
|
|
|
Provides named get_init method, set_I and clear_I methods. |
1850
|
|
|
|
|
|
|
|
1851
|
|
|
|
|
|
|
=back |
1852
|
|
|
|
|
|
|
|
1853
|
|
|
|
|
|
|
B: The following types of accessor methods are available. |
1854
|
|
|
|
|
|
|
|
1855
|
|
|
|
|
|
|
=over 4 |
1856
|
|
|
|
|
|
|
|
1857
|
|
|
|
|
|
|
=item get_set |
1858
|
|
|
|
|
|
|
|
1859
|
|
|
|
|
|
|
The get_set method, if called with a reference to an object of the |
1860
|
|
|
|
|
|
|
given class as the first argument, stores it. |
1861
|
|
|
|
|
|
|
|
1862
|
|
|
|
|
|
|
If called with any other arguments, creates and stores a new object, passing the arguemnts to the new() method for the object. |
1863
|
|
|
|
|
|
|
|
1864
|
|
|
|
|
|
|
If called without arguments, returns the current value, which may be undefined if one has not been stored yet. |
1865
|
|
|
|
|
|
|
|
1866
|
|
|
|
|
|
|
=item get_set_init |
1867
|
|
|
|
|
|
|
|
1868
|
|
|
|
|
|
|
The get_set_init method, if called with a reference to an object of the |
1869
|
|
|
|
|
|
|
given class as the first argument, stores it. |
1870
|
|
|
|
|
|
|
|
1871
|
|
|
|
|
|
|
If the slot is not filled yet it creates an object by calling the given |
1872
|
|
|
|
|
|
|
new method of the given class. Any arguments passed to the get_set_init |
1873
|
|
|
|
|
|
|
method are passed on to new. |
1874
|
|
|
|
|
|
|
|
1875
|
|
|
|
|
|
|
In all cases the object now stored is returned. |
1876
|
|
|
|
|
|
|
|
1877
|
|
|
|
|
|
|
=item get_init |
1878
|
|
|
|
|
|
|
|
1879
|
|
|
|
|
|
|
If the instance is empty, creates and stores a new one. Returns the instance. |
1880
|
|
|
|
|
|
|
|
1881
|
|
|
|
|
|
|
=item get |
1882
|
|
|
|
|
|
|
|
1883
|
|
|
|
|
|
|
Returns the current value, which may be undefined if one has not been stored yet. |
1884
|
|
|
|
|
|
|
|
1885
|
|
|
|
|
|
|
=item set |
1886
|
|
|
|
|
|
|
|
1887
|
|
|
|
|
|
|
If called with a reference to an object of the given class as the first argument, stores it. |
1888
|
|
|
|
|
|
|
|
1889
|
|
|
|
|
|
|
If called with any other arguments, creates and stores a new object, passing the arguments to the new() method. |
1890
|
|
|
|
|
|
|
|
1891
|
|
|
|
|
|
|
If called without arguments, creates and stores a new object, without any arguments to the new() method. |
1892
|
|
|
|
|
|
|
|
1893
|
|
|
|
|
|
|
=item clear |
1894
|
|
|
|
|
|
|
|
1895
|
|
|
|
|
|
|
Removes the reference value. |
1896
|
|
|
|
|
|
|
|
1897
|
|
|
|
|
|
|
=item I |
1898
|
|
|
|
|
|
|
|
1899
|
|
|
|
|
|
|
If a 'delegate' or 'soft_delegate' parameter is provided, methods |
1900
|
|
|
|
|
|
|
with those names are created that are forwarded directly to the |
1901
|
|
|
|
|
|
|
object in the slot, as described below. |
1902
|
|
|
|
|
|
|
|
1903
|
|
|
|
|
|
|
=back |
1904
|
|
|
|
|
|
|
|
1905
|
|
|
|
|
|
|
B: The following parameters are supported: |
1906
|
|
|
|
|
|
|
|
1907
|
|
|
|
|
|
|
=over 4 |
1908
|
|
|
|
|
|
|
|
1909
|
|
|
|
|
|
|
=item class |
1910
|
|
|
|
|
|
|
|
1911
|
|
|
|
|
|
|
I. The type of object that will be stored. |
1912
|
|
|
|
|
|
|
|
1913
|
|
|
|
|
|
|
=item new_method |
1914
|
|
|
|
|
|
|
|
1915
|
|
|
|
|
|
|
The name of the method to call on the above class to create a new instance. Defaults to 'new'. |
1916
|
|
|
|
|
|
|
|
1917
|
|
|
|
|
|
|
=item delegate |
1918
|
|
|
|
|
|
|
|
1919
|
|
|
|
|
|
|
The methods to forward to the object. Can contain a method name, |
1920
|
|
|
|
|
|
|
a string of space-spearated method names, or an array of method |
1921
|
|
|
|
|
|
|
names. This type of method will croak if it is called when the |
1922
|
|
|
|
|
|
|
target object is not defined. |
1923
|
|
|
|
|
|
|
|
1924
|
|
|
|
|
|
|
=item soft_delegate |
1925
|
|
|
|
|
|
|
|
1926
|
|
|
|
|
|
|
The methods to forward to the object, if it is present. Can contain |
1927
|
|
|
|
|
|
|
a method name, a string of space-spearated method names, or an |
1928
|
|
|
|
|
|
|
array of method names. This type of method will return nothing if |
1929
|
|
|
|
|
|
|
it is called when the target object is not defined. |
1930
|
|
|
|
|
|
|
|
1931
|
|
|
|
|
|
|
=back |
1932
|
|
|
|
|
|
|
|
1933
|
|
|
|
|
|
|
=cut |
1934
|
|
|
|
|
|
|
|
1935
|
|
|
|
|
|
|
sub object { |
1936
|
|
|
|
|
|
|
{ |
1937
|
|
|
|
|
|
|
'-import' => { |
1938
|
|
|
|
|
|
|
# 'Template::Generic:generic' => '*', |
1939
|
|
|
|
|
|
|
}, |
1940
|
|
|
|
|
|
|
'interface' => { |
1941
|
|
|
|
|
|
|
default => { '*'=>'get_set', 'clear_*'=>'clear' }, |
1942
|
|
|
|
|
|
|
get_set_init => { '*'=>'get_set_init', 'clear_*'=>'clear' }, |
1943
|
|
|
|
|
|
|
get_and_set => {'*'=>'get', 'set_*'=>'set', 'clear_*'=>'clear' }, |
1944
|
|
|
|
|
|
|
get_init_and_set => { '*'=>'get_init','set_*'=>'set','clear_*'=>'clear' }, |
1945
|
|
|
|
|
|
|
init_and_get => { '*'=>'init_and_get', -params=>{ init_method=>'init_*' } }, |
1946
|
|
|
|
|
|
|
}, |
1947
|
|
|
|
|
|
|
'params' => { |
1948
|
|
|
|
|
|
|
new_method => 'new' |
1949
|
|
|
|
|
|
|
}, |
1950
|
|
|
|
|
|
|
'code_expr' => { |
1951
|
|
|
|
|
|
|
'_CALL_NEW_AND_STORE_' => q{ |
1952
|
|
|
|
|
|
|
my $new_method = _ATTR_REQUIRED_{new_method}; |
1953
|
|
|
|
|
|
|
my $class = _ATTR_REQUIRED_{'class'}; |
1954
|
|
|
|
|
|
|
_SET_VALUE_{ $class->$new_method(@_) }; |
1955
|
|
|
|
|
|
|
}, |
1956
|
|
|
|
|
|
|
}, |
1957
|
|
|
|
|
|
|
'behavior' => { |
1958
|
|
|
|
|
|
|
'-import' => { |
1959
|
|
|
|
|
|
|
'Template::Generic:scalar' => [ qw( get clear ) ], |
1960
|
|
|
|
|
|
|
}, |
1961
|
|
|
|
|
|
|
'get_set' => q{ |
1962
|
|
|
|
|
|
|
if ( scalar @_ ) { |
1963
|
|
|
|
|
|
|
if (ref $_[0] and UNIVERSAL::isa($_[0], _ATTR_REQUIRED_{'class'})) { |
1964
|
|
|
|
|
|
|
_SET_VALUE_{ shift }; |
1965
|
|
|
|
|
|
|
} else { |
1966
|
|
|
|
|
|
|
_CALL_NEW_AND_STORE_ |
1967
|
|
|
|
|
|
|
} |
1968
|
|
|
|
|
|
|
} else { |
1969
|
|
|
|
|
|
|
_VALUE_; |
1970
|
|
|
|
|
|
|
} |
1971
|
|
|
|
|
|
|
}, |
1972
|
|
|
|
|
|
|
'set' => q{ |
1973
|
|
|
|
|
|
|
if ( ! defined $_[0] ) { |
1974
|
|
|
|
|
|
|
_SET_VALUE_{ undef }; |
1975
|
|
|
|
|
|
|
} elsif (ref $_[0] and UNIVERSAL::isa($_[0], _ATTR_REQUIRED_{'class'})) { |
1976
|
|
|
|
|
|
|
_SET_VALUE_{ shift }; |
1977
|
|
|
|
|
|
|
} else { |
1978
|
|
|
|
|
|
|
_CALL_NEW_AND_STORE_ |
1979
|
|
|
|
|
|
|
} |
1980
|
|
|
|
|
|
|
}, |
1981
|
|
|
|
|
|
|
'get_init' => q{ |
1982
|
|
|
|
|
|
|
if ( ! defined _VALUE_ ) { |
1983
|
|
|
|
|
|
|
_CALL_NEW_AND_STORE_ |
1984
|
|
|
|
|
|
|
} |
1985
|
|
|
|
|
|
|
_VALUE_; |
1986
|
|
|
|
|
|
|
}, |
1987
|
|
|
|
|
|
|
'init_and_get' => q{ |
1988
|
|
|
|
|
|
|
if ( ! defined _VALUE_ ) { |
1989
|
|
|
|
|
|
|
my $init_method = _ATTR_REQUIRED_{'init_method'}; |
1990
|
|
|
|
|
|
|
_SET_VALUE_{ _SELF_->$init_method( @_ ) }; |
1991
|
|
|
|
|
|
|
} else { |
1992
|
|
|
|
|
|
|
_BEHAVIOR_{get} |
1993
|
|
|
|
|
|
|
} |
1994
|
|
|
|
|
|
|
}, |
1995
|
|
|
|
|
|
|
'get_set_init' => q{ |
1996
|
|
|
|
|
|
|
if (ref $_[0] and UNIVERSAL::isa($_[0], _ATTR_REQUIRED_{'class'})) { |
1997
|
|
|
|
|
|
|
_SET_VALUE_{ shift }; |
1998
|
|
|
|
|
|
|
} elsif ( ! defined _VALUE_ ) { |
1999
|
|
|
|
|
|
|
_CALL_NEW_AND_STORE_ |
2000
|
|
|
|
|
|
|
} |
2001
|
|
|
|
|
|
|
_VALUE_; |
2002
|
|
|
|
|
|
|
}, |
2003
|
|
|
|
|
|
|
'-subs' => sub { |
2004
|
|
|
|
|
|
|
{ |
2005
|
8
|
|
|
|
|
16
|
'delegate' => sub { my($m_info, $name) = @_; sub { |
2006
|
0
|
|
|
23
|
|
0
|
my $m_name = $m_info->{'name'}; |
|
23
|
|
|
|
|
609
|
|
2007
|
0
|
0
|
|
|
|
0
|
my $obj = (shift)->$m_name() |
|
23
|
50
|
|
|
|
824
|
|
2008
|
|
|
|
|
|
|
or Carp::croak("Can't forward $name because $m_name is empty"); |
2009
|
0
|
|
|
|
|
0
|
$obj->$name(@_) |
|
30
|
|
|
|
|
140
|
|
2010
|
8
|
|
|
|
|
82
|
} }, |
2011
|
0
|
|
|
|
|
0
|
'soft_delegate' => sub { my($m_info, $name) = @_; sub { |
2012
|
0
|
|
|
|
|
0
|
my $m_name = $m_info->{'name'}; |
2013
|
0
|
0
|
|
|
|
0
|
my $obj = (shift)->$m_name() or return; |
2014
|
0
|
|
|
|
|
0
|
$obj->$name(@_) |
2015
|
0
|
|
|
|
|
0
|
} }, |
2016
|
|
|
|
|
|
|
} |
2017
|
26
|
|
|
26
|
|
238
|
}, |
2018
|
|
|
|
|
|
|
}, |
2019
|
|
|
|
|
|
|
} |
2020
|
6
|
|
|
6
|
1
|
234
|
} |
2021
|
|
|
|
|
|
|
|
2022
|
|
|
|
|
|
|
######################################################################## |
2023
|
|
|
|
|
|
|
|
2024
|
|
|
|
|
|
|
=head2 instance Accessor |
2025
|
|
|
|
|
|
|
|
2026
|
|
|
|
|
|
|
Creates methods to handle an instance of the calling class. |
2027
|
|
|
|
|
|
|
|
2028
|
|
|
|
|
|
|
PROFILES |
2029
|
|
|
|
|
|
|
|
2030
|
|
|
|
|
|
|
=over 4 |
2031
|
|
|
|
|
|
|
|
2032
|
|
|
|
|
|
|
=item default |
2033
|
|
|
|
|
|
|
|
2034
|
|
|
|
|
|
|
Provides named get method, and I_I set, new, and clear methods. |
2035
|
|
|
|
|
|
|
|
2036
|
|
|
|
|
|
|
=item -implicit_new |
2037
|
|
|
|
|
|
|
|
2038
|
|
|
|
|
|
|
Provides named get_init method, and I_I set, and clear methods. |
2039
|
|
|
|
|
|
|
|
2040
|
|
|
|
|
|
|
=item -x_verb |
2041
|
|
|
|
|
|
|
|
2042
|
|
|
|
|
|
|
Provides named get method, and I_I set, new, and clear methods. |
2043
|
|
|
|
|
|
|
|
2044
|
|
|
|
|
|
|
=back |
2045
|
|
|
|
|
|
|
|
2046
|
|
|
|
|
|
|
B: The following types of accessor methods are available. |
2047
|
|
|
|
|
|
|
|
2048
|
|
|
|
|
|
|
=over 4 |
2049
|
|
|
|
|
|
|
|
2050
|
|
|
|
|
|
|
=item get |
2051
|
|
|
|
|
|
|
|
2052
|
|
|
|
|
|
|
Returns the value of the instance parameter, which may be undefined if one has not been stored yet. |
2053
|
|
|
|
|
|
|
|
2054
|
|
|
|
|
|
|
=item get_init |
2055
|
|
|
|
|
|
|
|
2056
|
|
|
|
|
|
|
If the instance is empty, creates and stores a new one. Returns the instance. |
2057
|
|
|
|
|
|
|
|
2058
|
|
|
|
|
|
|
=item set |
2059
|
|
|
|
|
|
|
|
2060
|
|
|
|
|
|
|
Takes a single argument and sets the instance to that value. |
2061
|
|
|
|
|
|
|
|
2062
|
|
|
|
|
|
|
=item new |
2063
|
|
|
|
|
|
|
|
2064
|
|
|
|
|
|
|
Creates and stores a new instance. |
2065
|
|
|
|
|
|
|
|
2066
|
|
|
|
|
|
|
=item clear |
2067
|
|
|
|
|
|
|
|
2068
|
|
|
|
|
|
|
Sets the instance parameter to undef. |
2069
|
|
|
|
|
|
|
|
2070
|
|
|
|
|
|
|
=back |
2071
|
|
|
|
|
|
|
|
2072
|
|
|
|
|
|
|
B: The following parameters are supported: |
2073
|
|
|
|
|
|
|
|
2074
|
|
|
|
|
|
|
=over 4 |
2075
|
|
|
|
|
|
|
|
2076
|
|
|
|
|
|
|
=item instance |
2077
|
|
|
|
|
|
|
|
2078
|
|
|
|
|
|
|
Holds the instance reference. Defaults to undef |
2079
|
|
|
|
|
|
|
|
2080
|
|
|
|
|
|
|
=item new_method |
2081
|
|
|
|
|
|
|
|
2082
|
|
|
|
|
|
|
The name of the method to call when creating a new instance. Defaults to 'new'. |
2083
|
|
|
|
|
|
|
|
2084
|
|
|
|
|
|
|
=back |
2085
|
|
|
|
|
|
|
|
2086
|
|
|
|
|
|
|
=cut |
2087
|
|
|
|
|
|
|
|
2088
|
|
|
|
|
|
|
sub instance { |
2089
|
|
|
|
|
|
|
{ |
2090
|
2
|
|
|
2
|
1
|
22
|
'-import' => { |
2091
|
|
|
|
|
|
|
'Template::Generic:object' => '*', |
2092
|
|
|
|
|
|
|
}, |
2093
|
|
|
|
|
|
|
'interface' => { |
2094
|
|
|
|
|
|
|
default => 'get_set', |
2095
|
|
|
|
|
|
|
}, |
2096
|
|
|
|
|
|
|
'code_expr' => { |
2097
|
|
|
|
|
|
|
'_CALL_NEW_AND_STORE_' => q{ |
2098
|
|
|
|
|
|
|
my $new_method = _ATTR_REQUIRED_{new_method}; |
2099
|
|
|
|
|
|
|
_SET_VALUE_{ (_SELF_)->$new_method(@_) }; |
2100
|
|
|
|
|
|
|
}, |
2101
|
|
|
|
|
|
|
}, |
2102
|
|
|
|
|
|
|
} |
2103
|
|
|
|
|
|
|
} |
2104
|
|
|
|
|
|
|
|
2105
|
|
|
|
|
|
|
######################################################################## |
2106
|
|
|
|
|
|
|
|
2107
|
|
|
|
|
|
|
=head2 array_of_objects Accessor |
2108
|
|
|
|
|
|
|
|
2109
|
|
|
|
|
|
|
Creates accessor methods for manipulating references to arrays of object references. |
2110
|
|
|
|
|
|
|
|
2111
|
|
|
|
|
|
|
Operates like C, but prior to adding any item to |
2112
|
|
|
|
|
|
|
the array, it first checks to see if it is an instance of the |
2113
|
|
|
|
|
|
|
designated class, and if not passes it as an argument to that |
2114
|
|
|
|
|
|
|
class's new method and stores the result instead. |
2115
|
|
|
|
|
|
|
|
2116
|
|
|
|
|
|
|
Forwarded methods return a list of the results returned |
2117
|
|
|
|
|
|
|
by C |
2118
|
|
|
|
|
|
|
|
2119
|
|
|
|
|
|
|
See the documentation on C for interfaces and behaviors. |
2120
|
|
|
|
|
|
|
|
2121
|
|
|
|
|
|
|
B: The following parameters are supported: |
2122
|
|
|
|
|
|
|
|
2123
|
|
|
|
|
|
|
=over 4 |
2124
|
|
|
|
|
|
|
|
2125
|
|
|
|
|
|
|
=item class |
2126
|
|
|
|
|
|
|
|
2127
|
|
|
|
|
|
|
I. The type of object that will be stored. |
2128
|
|
|
|
|
|
|
|
2129
|
|
|
|
|
|
|
=item delegate |
2130
|
|
|
|
|
|
|
|
2131
|
|
|
|
|
|
|
The methods to forward to the object. Can contain a method name, a string of space-spearated method names, or an array of method names. |
2132
|
|
|
|
|
|
|
|
2133
|
|
|
|
|
|
|
=item new_method |
2134
|
|
|
|
|
|
|
|
2135
|
|
|
|
|
|
|
The name of the method to call on the above class to create a new instance. Defaults to 'new'. |
2136
|
|
|
|
|
|
|
|
2137
|
|
|
|
|
|
|
=back |
2138
|
|
|
|
|
|
|
|
2139
|
|
|
|
|
|
|
=cut |
2140
|
|
|
|
|
|
|
|
2141
|
|
|
|
|
|
|
sub array_of_objects { |
2142
|
|
|
|
|
|
|
{ |
2143
|
|
|
|
|
|
|
'-import' => { |
2144
|
|
|
|
|
|
|
'Template::Generic:array' => '*', |
2145
|
|
|
|
|
|
|
}, |
2146
|
|
|
|
|
|
|
'params' => { |
2147
|
|
|
|
|
|
|
new_method => 'new', |
2148
|
|
|
|
|
|
|
}, |
2149
|
|
|
|
|
|
|
'modifier' => { |
2150
|
|
|
|
|
|
|
'-all get_set' => q{ _BLESS_ARGS_ * }, |
2151
|
|
|
|
|
|
|
'-all get_push' => q{ _BLESS_ARGS_ * }, |
2152
|
|
|
|
|
|
|
'-all set' => q{ _BLESS_ARGS_ * }, |
2153
|
|
|
|
|
|
|
'-all push' => q{ _BLESS_ARGS_ * }, |
2154
|
|
|
|
|
|
|
'-all unshift' => q{ _BLESS_ARGS_ * }, |
2155
|
|
|
|
|
|
|
# The below two methods are kinda broken, because the new values |
2156
|
|
|
|
|
|
|
# don't get auto-blessed properly... |
2157
|
|
|
|
|
|
|
'-all splice' => q{ * }, |
2158
|
|
|
|
|
|
|
'-all set_items' => q{ * }, |
2159
|
|
|
|
|
|
|
}, |
2160
|
|
|
|
|
|
|
'code_expr' => { |
2161
|
|
|
|
|
|
|
'_BLESS_ARGS_' => q{ |
2162
|
|
|
|
|
|
|
my $new_method = _ATTR_REQUIRED_{'new_method'}; |
2163
|
|
|
|
|
|
|
@_ = map { |
2164
|
|
|
|
|
|
|
(ref $_ and UNIVERSAL::isa($_, _ATTR_REQUIRED_{class})) ? $_ |
2165
|
|
|
|
|
|
|
: _ATTR_{'class'}->$new_method($_) |
2166
|
|
|
|
|
|
|
} @_; |
2167
|
|
|
|
|
|
|
}, |
2168
|
|
|
|
|
|
|
}, |
2169
|
|
|
|
|
|
|
'behavior' => { |
2170
|
|
|
|
|
|
|
'-subs' => sub { |
2171
|
|
|
|
|
|
|
{ |
2172
|
3
|
|
|
|
|
9
|
'delegate' => sub { my($m_info, $name) = @_; sub { |
2173
|
0
|
|
|
|
|
0
|
my $m_name = $m_info->{'name'}; |
2174
|
0
|
|
|
|
|
0
|
map { $_->$name(@_) } (shift)->$m_name() |
|
0
|
|
|
|
|
0
|
|
2175
|
3
|
|
|
|
|
38
|
} }, |
2176
|
|
|
|
|
|
|
} |
2177
|
3
|
|
|
3
|
|
1735
|
}, |
2178
|
|
|
|
|
|
|
}, |
2179
|
|
|
|
|
|
|
} |
2180
|
3
|
|
|
3
|
1
|
65
|
} |
2181
|
|
|
|
|
|
|
|
2182
|
|
|
|
|
|
|
######################################################################## |
2183
|
|
|
|
|
|
|
|
2184
|
|
|
|
|
|
|
=head2 code Accessor |
2185
|
|
|
|
|
|
|
|
2186
|
|
|
|
|
|
|
Creates accessor methods for manipulating references to subroutines. |
2187
|
|
|
|
|
|
|
|
2188
|
|
|
|
|
|
|
B: The following calling interfaces are available. |
2189
|
|
|
|
|
|
|
|
2190
|
|
|
|
|
|
|
=over 4 |
2191
|
|
|
|
|
|
|
|
2192
|
|
|
|
|
|
|
=item default |
2193
|
|
|
|
|
|
|
|
2194
|
|
|
|
|
|
|
Provides the call_set functionality. |
2195
|
|
|
|
|
|
|
|
2196
|
|
|
|
|
|
|
=item method |
2197
|
|
|
|
|
|
|
|
2198
|
|
|
|
|
|
|
Provides the call_method functionality. |
2199
|
|
|
|
|
|
|
|
2200
|
|
|
|
|
|
|
=back |
2201
|
|
|
|
|
|
|
|
2202
|
|
|
|
|
|
|
B: The following types of accessor methods are available. |
2203
|
|
|
|
|
|
|
|
2204
|
|
|
|
|
|
|
=over 4 |
2205
|
|
|
|
|
|
|
|
2206
|
|
|
|
|
|
|
=item call_set |
2207
|
|
|
|
|
|
|
|
2208
|
|
|
|
|
|
|
If called with one argument which is a CODE reference, it installs that |
2209
|
|
|
|
|
|
|
code in the slot. Otherwise it runs the code stored in the slot with |
2210
|
|
|
|
|
|
|
whatever arguments (including none) were passed in. |
2211
|
|
|
|
|
|
|
|
2212
|
|
|
|
|
|
|
=item call_method |
2213
|
|
|
|
|
|
|
|
2214
|
|
|
|
|
|
|
Just like B, except the code is called like a method, with $self |
2215
|
|
|
|
|
|
|
as its first argument. Basically, you are creating a method which can be |
2216
|
|
|
|
|
|
|
different for each object. |
2217
|
|
|
|
|
|
|
|
2218
|
|
|
|
|
|
|
=back |
2219
|
|
|
|
|
|
|
|
2220
|
|
|
|
|
|
|
=cut |
2221
|
|
|
|
|
|
|
|
2222
|
|
|
|
|
|
|
sub code { |
2223
|
|
|
|
|
|
|
{ |
2224
|
5
|
|
|
5
|
1
|
98
|
'-import' => { |
2225
|
|
|
|
|
|
|
# 'Template::Generic:generic' => '*', |
2226
|
|
|
|
|
|
|
}, |
2227
|
|
|
|
|
|
|
'interface' => { |
2228
|
|
|
|
|
|
|
default => 'call_set', |
2229
|
|
|
|
|
|
|
call_set => 'call_set', |
2230
|
|
|
|
|
|
|
method => 'call_method', |
2231
|
|
|
|
|
|
|
}, |
2232
|
|
|
|
|
|
|
'behavior' => { |
2233
|
|
|
|
|
|
|
'-import' => { |
2234
|
|
|
|
|
|
|
'Template::Generic:scalar' => [ qw( get_set get set clear ) ], |
2235
|
|
|
|
|
|
|
}, |
2236
|
|
|
|
|
|
|
'call_set' => q{ |
2237
|
|
|
|
|
|
|
if ( scalar @_ == 1 and ref($_[0]) eq 'CODE') { |
2238
|
|
|
|
|
|
|
_SET_VALUE_{ shift }; # Set the subroutine reference |
2239
|
|
|
|
|
|
|
} else { |
2240
|
|
|
|
|
|
|
&{ _VALUE_ }( @_ ); # Run the subroutine on the given arguments |
2241
|
|
|
|
|
|
|
} |
2242
|
|
|
|
|
|
|
}, |
2243
|
|
|
|
|
|
|
'call_method' => q{ |
2244
|
|
|
|
|
|
|
if ( scalar @_ == 1 and ref($_[0]) eq 'CODE') { |
2245
|
|
|
|
|
|
|
_SET_VALUE_{ shift }; # Set the subroutine reference |
2246
|
|
|
|
|
|
|
} else { |
2247
|
|
|
|
|
|
|
&{ _VALUE_ }( _SELF_, @_ ); # Run the subroutine on self and args |
2248
|
|
|
|
|
|
|
} |
2249
|
|
|
|
|
|
|
}, |
2250
|
|
|
|
|
|
|
}, |
2251
|
|
|
|
|
|
|
} |
2252
|
|
|
|
|
|
|
} |
2253
|
|
|
|
|
|
|
|
2254
|
|
|
|
|
|
|
|
2255
|
|
|
|
|
|
|
######################################################################## |
2256
|
|
|
|
|
|
|
|
2257
|
|
|
|
|
|
|
=head2 code_or_scalar Accessor |
2258
|
|
|
|
|
|
|
|
2259
|
|
|
|
|
|
|
Creates accessor methods for manipulating either strings or references to subroutines. |
2260
|
|
|
|
|
|
|
|
2261
|
|
|
|
|
|
|
You can store any scalar value; code refs are executed when you retrieve the value, while other scalars are returned as-is. |
2262
|
|
|
|
|
|
|
|
2263
|
|
|
|
|
|
|
B: The following calling interfaces are available. |
2264
|
|
|
|
|
|
|
|
2265
|
|
|
|
|
|
|
=over 4 |
2266
|
|
|
|
|
|
|
|
2267
|
|
|
|
|
|
|
=item default |
2268
|
|
|
|
|
|
|
|
2269
|
|
|
|
|
|
|
Provides the call_set functionality. |
2270
|
|
|
|
|
|
|
|
2271
|
|
|
|
|
|
|
=item method |
2272
|
|
|
|
|
|
|
|
2273
|
|
|
|
|
|
|
Provides the call_method functionality. |
2274
|
|
|
|
|
|
|
|
2275
|
|
|
|
|
|
|
=item eiffel |
2276
|
|
|
|
|
|
|
|
2277
|
|
|
|
|
|
|
Provides the named get_method, and a helper set_* method. |
2278
|
|
|
|
|
|
|
|
2279
|
|
|
|
|
|
|
=back |
2280
|
|
|
|
|
|
|
|
2281
|
|
|
|
|
|
|
B: The following types of accessor methods are available. |
2282
|
|
|
|
|
|
|
|
2283
|
|
|
|
|
|
|
=over 4 |
2284
|
|
|
|
|
|
|
|
2285
|
|
|
|
|
|
|
=item get_set_call |
2286
|
|
|
|
|
|
|
|
2287
|
|
|
|
|
|
|
If called with an argument, either a CODE reference or some other scalar, it installs that code in the slot. Otherwise, if the current value runs the code stored in the slot with |
2288
|
|
|
|
|
|
|
whatever arguments (including none) were passed in. |
2289
|
|
|
|
|
|
|
|
2290
|
|
|
|
|
|
|
=item get_set_method |
2291
|
|
|
|
|
|
|
|
2292
|
|
|
|
|
|
|
Just like B, except the code is called like a method, with $self |
2293
|
|
|
|
|
|
|
as its first argument. Basically, you are creating a method which can be |
2294
|
|
|
|
|
|
|
different for each object. |
2295
|
|
|
|
|
|
|
|
2296
|
|
|
|
|
|
|
=back |
2297
|
|
|
|
|
|
|
|
2298
|
|
|
|
|
|
|
=cut |
2299
|
|
|
|
|
|
|
|
2300
|
|
|
|
|
|
|
sub code_or_scalar { |
2301
|
|
|
|
|
|
|
{ |
2302
|
0
|
|
|
0
|
1
|
0
|
'-import' => { 'Template::Generic:scalar' => '*' }, |
2303
|
|
|
|
|
|
|
'interface' => { |
2304
|
|
|
|
|
|
|
default => 'get_set_call', |
2305
|
|
|
|
|
|
|
get_set => 'get_set_call', |
2306
|
|
|
|
|
|
|
eiffel => { '*'=>'get_method', 'set_*'=>'set' }, |
2307
|
|
|
|
|
|
|
method => 'get_set_method', |
2308
|
|
|
|
|
|
|
}, |
2309
|
|
|
|
|
|
|
'params' => { |
2310
|
|
|
|
|
|
|
}, |
2311
|
|
|
|
|
|
|
'behavior' => { |
2312
|
|
|
|
|
|
|
'get_call' => q{ |
2313
|
|
|
|
|
|
|
my $value = _GET_VALUE_; |
2314
|
|
|
|
|
|
|
( ref($value) eq 'CODE' ) ? &$value( @_ ) : $value |
2315
|
|
|
|
|
|
|
}, |
2316
|
|
|
|
|
|
|
'get_method' => q{ |
2317
|
|
|
|
|
|
|
my $value = _GET_VALUE_; |
2318
|
|
|
|
|
|
|
( ref($value) eq 'CODE' ) ? &$value( _SELF_, @_ ) : $value |
2319
|
|
|
|
|
|
|
}, |
2320
|
|
|
|
|
|
|
'get_set_call' => q{ |
2321
|
|
|
|
|
|
|
if ( scalar @_ == 1 ) { |
2322
|
|
|
|
|
|
|
_BEHAVIOR_{set} |
2323
|
|
|
|
|
|
|
} else { |
2324
|
|
|
|
|
|
|
_BEHAVIOR_{get_call} |
2325
|
|
|
|
|
|
|
} |
2326
|
|
|
|
|
|
|
}, |
2327
|
|
|
|
|
|
|
'get_set_method' => q{ |
2328
|
|
|
|
|
|
|
if ( scalar @_ == 1 ) { |
2329
|
|
|
|
|
|
|
_BEHAVIOR_{set} |
2330
|
|
|
|
|
|
|
} else { |
2331
|
|
|
|
|
|
|
_BEHAVIOR_{get_call} |
2332
|
|
|
|
|
|
|
} |
2333
|
|
|
|
|
|
|
}, |
2334
|
|
|
|
|
|
|
}, |
2335
|
|
|
|
|
|
|
} |
2336
|
|
|
|
|
|
|
} |
2337
|
|
|
|
|
|
|
|
2338
|
|
|
|
|
|
|
|
2339
|
|
|
|
|
|
|
######################################################################## |
2340
|
|
|
|
|
|
|
|
2341
|
|
|
|
|
|
|
=head1 SEE ALSO |
2342
|
|
|
|
|
|
|
|
2343
|
|
|
|
|
|
|
See L for general information about this distribution. |
2344
|
|
|
|
|
|
|
|
2345
|
|
|
|
|
|
|
See L for information about this family of subclasses. |
2346
|
|
|
|
|
|
|
|
2347
|
|
|
|
|
|
|
=cut |
2348
|
|
|
|
|
|
|
|
2349
|
|
|
|
|
|
|
1; |