1Rose::Object::MakeMethoUdsse(r3)Contributed Perl DocumenRtoastei:o:nObject::MakeMethods(3)
2
3
4
6 Rose::Object::MakeMethods - A simple method maker base class.
7
9 package MyMethodMaker;
10
11 use Rose::Object::MakeMethods;
12 our @ISA = qw(Rose::Object::MakeMethods);
13
14 sub widget
15 {
16 my($class, $name, $args) = @_;
17
18 my $key = $args->{'hash_key'} || $name;
19 my $interface = $args->{'interface'} || 'get_set';
20
21 my %methods;
22
23 if($interface =~ /^get_set/)
24 {
25 $methods{$name} = sub
26 {
27 my($self) = shift;
28 if(@_) { ... }
29 ...
30 return $self->{$key};
31 };
32 }
33
34 if($interface eq 'get_set_delete')
35 {
36 $methods{"delete_$name"} = sub { ... };
37 )
38
39 return \%methods;
40 }
41 ...
42
43 package MyObject;
44
45 sub new { ... }
46
47 use MyMethodMaker
48 (
49 'widget --get_set_delete' => 'foo',
50
51 'widget' =>
52 [
53 'bar',
54 'baz',
55 ]
56 );
57 ...
58
59 $o = MyObject->new;
60
61 $o->foo($bar);
62 $o->delete_foo();
63
64 print $o->bar . $o->baz;
65 ...
66
68 Rose::Object::MakeMethods is the base class for a family of method
69 makers. A method maker is a module that's used to define methods in
70 other packages. The actual method makers are subclasses of
71 Rose::Object::MakeMethods that define the names and options of the
72 different kinds of methods that they can make.
73
74 There are method makers that make both object methods and class
75 methods. The object method makers are in the
76 "Rose::Object::MakeMethods::*" namespace. The class method makers are
77 in the "Rose::Class::MakeMethods::*" namespace for the sake of clarity,
78 but still inherit from Class::MethodMaker and therefore share the same
79 method making interface.
80
81 Several useful method makers are included under the
82 "Rose::Object::MakeMethods::*" and "Rose::Class::MakeMethods::*"
83 namespaces, mostly for use by other "Rose::*" objects and classes.
84
85 This family of modules is not as powerful or flexible as the one that
86 inspired it: Class::MethodMaker. I found that I was only using a tiny
87 corner of the functionality provided by Class::MethodMaker, so I wrote
88 this as a simple, smaller replacement.
89
90 The fact that many "Rose::*" modules use Rose::Object::MakeMethods
91 subclasses to make their methods should be considered an implementation
92 detail that can change at any time.
93
95 allow_apparent_reload [BOOL]
96 Get or set an attribute that determines whether or not to allow an
97 attempt to re-make the same method using the same class that made
98 it earlier. The default is true.
99
100 This issue comes up when a module is forcibly reloaded, e.g., by
101 Apache::Reload or Apache::StatINC. When this happens, all the
102 "make methods" actions will be attempted again. In the absence of
103 the "preserve_existing" or "override_existing" options, the
104 allow_apparent_reload attribute will be consulted. If it's true,
105 and if it appears that the method in question was made by this
106 method-maker class, then it behaves as if the "preserve_existing"
107 option had been passed. If it is false, then a fatal "method
108 redefined" error will occur.
109
110 import SPEC
111 The "import" class method is mean to be called implicitly as a
112 result of a "use" statement. For example:
113
114 use Rose::Object::MakeMethods::Generic
115 (
116 SPEC
117 );
118
119 is roughly equivalent to:
120
121 require Rose::Object::MakeMethods::Generic;
122 Rose::Object::MakeMethods::Generic->import(SPEC);
123
124 where SPEC is a series of specifications for the methods to be
125 created. (But don't call import explicitly; use make_methods
126 instead.)
127
128 In response to each method specification, one or more methods are
129 created.
130
131 The first part of the SPEC argument is an optional hash reference
132 whose contents are intended to modify the behavior of the method
133 maker class itself, rather than the individual methods being made.
134 There are currently only two valid arguments for this hash:
135
136 target_class CLASS
137 Specifies that class that the methods will be added to.
138 Defaults to the class from which the call was made. For
139 example, this:
140
141 use Rose::Object::MakeMethods::Generic
142 (
143 { target_class => 'Foo' },
144 ...
145 );
146
147 Is equivalent to this:
148
149 package Foo;
150
151 use Rose::Object::MakeMethods::Generic
152 (
153 ...
154 );
155
156 In general, the "target_class" argument is omitted since
157 methods are usually indented to end up in the class of the
158 caller.
159
160 override_existing BOOL
161 By default, attempting to create a method that already exists
162 will result in a fatal error. But if the "override_existing"
163 option is set to a true value, the existing method will be
164 replaced with the generated method.
165
166 preserve_existing BOOL
167 By default, attempting to create a method that already exists
168 will result in a fatal error. But if the "preserve_existing"
169 option is set to a true value, the existing method will be left
170 unmodified. This option takes precedence over the
171 "override_existing" option.
172
173 After the optional hash reference full off options intended for the
174 method maker class itself, a series of method specifications should
175 be provided. Each method specification defines one or more named
176 methods. The components of such a specification are:
177
178 • The Method Type
179
180 This is the name of the subroutine that will be called in order
181 to generated the methods (see SUBCLASSING for more
182 information). It describes the nature of the generated method.
183 For example, "scalar", "array", "bitfield", "object"
184
185 • Method Type Arguments
186
187 Name/value pairs that are passed to the method maker of the
188 specified type in order to modify its behavior.
189
190 • Method Names
191
192 One or more names for the methods that are to be created. Note
193 that a method maker of a particular type may choose to modify
194 or ignore these names. In the common case, for each method
195 name argument, a single method is created with the same name as
196 the method name argument.
197
198 Given the method type "bitfield" and the method arguments "opt1"
199 and "opt2", the following examples show all valid forms for method
200 specifications, with equivalent forms grouped together.
201
202 Create a bitfield method named "my_bits":
203
204 bitfield => 'my_bits'
205
206 bitfield => [ 'my_bits' ],
207
208 bitfield => [ 'my_bits' => {} ],
209
210 Create a bitfield method named "my_bits", passing the "opt1"
211 argument with a value of 2.
212
213 'bitfield --opt1=2' => 'my_bits'
214
215 'bitfield --opt1=2' => [ 'my_bits' ]
216
217 bitfield => [ 'my_bits' => { opt1 => 2 } ]
218
219 Create a bitfield method named "my_bits", passing the "opt1"
220 argument with a value of 2 and the "opt2" argument with a value of
221 7.
222
223 'bitfield --opt1=2 --opt2=7' => 'my_bits'
224
225 'bitfield --opt1=2 --opt2=7' => [ 'my_bits' ]
226
227 bitfield => [ 'my_bits' => { opt1 => 2, opt2 => 7 } ]
228
229 'bitfield --opt2=7' => [ 'my_bits' => { opt1 => 2 } ]
230
231 In the case of a conflict between the options specified with the
232 "--name=value" syntax and those provided in the hash reference, the
233 ones in the hash reference take precedence. For example, these are
234 equivalent:
235
236 'bitfield --opt1=99' => 'my_bits'
237
238 'bitfield --opt1=5' => [ 'my_bits' => { opt1 => 99 } ]
239
240 If no value is provided for the first option, and if it is
241 specified using the "--name" syntax, then it is taken as the value
242 of the "interface" option. That is, this:
243
244 'bitfield --foobar' => 'my_bits'
245
246 is equivalent to these:
247
248 'bitfield --interface=foobar' => 'my_bits'
249
250 bitfield => [ my_bits => { interface => 'foobar' } ]
251
252 This shortcut supports the convention that the "interface" option
253 is used to decide which set of methods to create. But it's just a
254 convention; the "interface" option is no different from any of the
255 other options when it is eventually passed to the method maker of a
256 given type.
257
258 Any option other than the very first that is specified using the
259 "--name" form and that lacks an explicit value is simply set to 1.
260 That is, this:
261
262 'bitfield --foobar --baz' => 'my_bits'
263
264 is equivalent to these:
265
266 'bitfield --interface=foobar --baz=1' => 'my_bits'
267
268 bitfield =>
269 [
270 my_bits => { interface => 'foobar', baz => 1 }
271 ]
272
273 Multiple method names can be specified simultaneously for a given
274 method type and set of options. For example, to create methods
275 named "my_bits[1-3]", all of the same type and with the same
276 options, any of these would work:
277
278 'bitfield --opt1=2' =>
279 [
280 'my_bits1',
281 'my_bits2',
282 'my_bits3',
283 ]
284
285 bitfield =>
286 [
287 'my_bits1' => { opt1 => 2 },
288 'my_bits2' => { opt1 => 2 },
289 'my_bits3' => { opt1 => 2 },
290 ]
291
292 When options are provided using the "--name=value" format, they
293 apply to all methods listed inside the array reference, unless
294 overridden. Here's an example of an override:
295
296 'bitfield --opt1=2' =>
297 [
298 'my_bits1',
299 'my_bits2',
300 'my_bits3' => { opt1 => 999 },
301 ]
302
303 In this case, "my_bits1" and "my_bits2" use "opt1" values of 2, but
304 "my_bits3" uses an "opt1" value of 999. Also note that it's okay
305 to mix bare method names ("my_bits1" and "my_bits2") with method
306 names that have associated hash reference options ("my_bits3"), all
307 inside the same array reference.
308
309 Finally, putting it all together, here's a full example using
310 several different formats.
311
312 use Rose::Object::MakeMethods::Generic
313 (
314 { override_existing => 1 },
315
316 'bitfield' => [ qw(my_bits other_bits) ],
317
318 'bitfield --opt1=5' =>
319 [
320 'a',
321 'b',
322 ],
323
324 'bitfield' =>
325 [
326 'c',
327 'd' => { opt2 => 7 },
328 'e' => { opt1 => 1 },
329 'f' => { }, # empty is okay too
330 ]
331 );
332
333 In the documentation for the various Rose::Object::MakeMethods
334 subclasses, any of the valid forms may be used in the examples.
335
336 make_methods SPEC
337 This method is equivalent to the "import" method, but makes the
338 intent of the code clearer when it is called explicitly. (The
339 "import" method is only meant to be called implicitly by "use".)
340
342 In order to make a Rose::Object::MakeMethods subclass that can actually
343 make some methods, simply subclass Rose::Object::MakeMethods and define
344 one subroutine for each method type you want to support.
345
346 The subroutine will be passed three arguments when it is called:
347
348 • The class of the method maker as a string. This argument is
349 usually ignored unless you are going to call some other class
350 method.
351
352 • The method name. In the common case, a single method with this
353 name is defined, but you are free to do whatever you want with it,
354 including ignoring it.
355
356 • A reference to a hash containing the options for the method.
357
358 The subroutine is expected to return a reference to a hash containing
359 name/code reference pairs. Note that the subroutine does not actually
360 install the methods. It simple returns the name of each method that is
361 to be installed, along with references to the closures that contain the
362 code for those methods.
363
364 This subroutine is called for each name in the method specifier. For
365 example, this would result in three separate calls to the "bitfield"
366 subroutine of the "MyMethodMaker" class:
367
368 use MyMethodMaker
369 (
370 bitfield =>
371 [
372 'my_bits',
373 'your_bits' => { size => 32 },
374 'other_bits' => { size => 128 },
375 ]
376 );
377
378 So why not have the subroutine return a single code reference rather
379 than a reference to a hash of name.code reference pairs? There are two
380 reasons.
381
382 First, remember that the name argument ("my_bits", "your_bits",
383 "other_bits") may be modified or ignored by the method maker. The
384 actual names of the methods created are determined by the keys of the
385 hash reference returned by the subroutine.
386
387 Second, a single call with a single method name argument may result in
388 the creation more than one method--usually a "family" of methods. For
389 example:
390
391 package MyObject;
392
393 use MyMethodMaker
394 (
395 # creates add_book(), delete_book(), and books() methods
396 'hash --manip' => 'book',
397 );
398 ...
399
400 $o = MyObject->new(...);
401
402 $o->add_book($book);
403
404 print join("\n", map { $_->title } $o->books);
405
406 $o->delete_book($book);
407
408 Here, the "hash" method type elected to create three methods by
409 prepending "add_" and "delete_" and appending "s" to the supplied
410 method name argument, "book".
411
412 Anything not specified in this documentation is simply a matter of
413 convention. For example, the Rose::Object::MakeMethods subclasses all
414 use a common set of method options: "hash_key", "interface", etc. As
415 you read their documentation, this will become apparent.
416
417 Finally, here's an example of a subclass that makes scalar accessors:
418
419 package Rose::Object::MakeMethods::Generic;
420
421 use strict;
422 use Carp();
423
424 use Rose::Object::MakeMethods;
425 our @ISA = qw(Rose::Object::MakeMethods);
426
427 sub scalar
428 {
429 my($class, $name, $args) = @_;
430
431 my %methods;
432
433 my $key = $args->{'hash_key'} || $name;
434 my $interface = $args->{'interface'} || 'get_set';
435
436 if($interface eq 'get_set_init')
437 {
438 my $init_method = $args->{'init_method'} || "init_$name";
439
440 $methods{$name} = sub
441 {
442 return $_[0]->{$key} = $_[1] if(@_ > 1);
443
444 return defined $_[0]->{$key} ? $_[0]->{$key} :
445 ($_[0]->{$key} = $_[0]->$init_method());
446 }
447 }
448 elsif($interface eq 'get_set')
449 {
450 $methods{$name} = sub
451 {
452 return $_[0]->{$key} = $_[1] if(@_ > 1);
453 return $_[0]->{$key};
454 }
455 }
456 else { Carp::croak "Unknown interface: $interface" }
457
458 return \%methods;
459 }
460
461 It can be used like this:
462
463 package MyObject;
464
465 use Rose::Object::MakeMethods::Generic
466 (
467 scalar =>
468 [
469 'power',
470 'error',
471 ],
472
473 'scalar --get_set_init' => 'name',
474 );
475
476 sub init_name { 'Fred' }
477 ...
478
479 $o = MyObject->new(power => 5);
480
481 print $o->name; # Fred
482
483 $o->power(99) or die $o->error;
484
485 This is actually a subset of the code in the actual
486 Rose::Object::MakeMethods::Generic module. See the rest of the
487 "Rose::Object::MakeMethods::*" and "Rose::Class::MakeMethods::*"
488 modules for more examples.
489
491 John C. Siracusa (siracusa@gmail.com)
492
494 Copyright (c) 2010 by John C. Siracusa. All rights reserved. This
495 program is free software; you can redistribute it and/or modify it
496 under the same terms as Perl itself.
497
498
499
500perl v5.32.1 2021-01-27 Rose::Object::MakeMethods(3)