1Class::AutoClass(3) User Contributed Perl Documentation Class::AutoClass(3)
2
3
4
6 Class::AutoClass - Create get and set methods and simplify object
7 initialization
8
10 Version 1.56
11
13 # code that defines class
14 #
15 package Person;
16 use base qw(Class::AutoClass);
17 use vars qw(@AUTO_ATTRIBUTES @OTHER_ATTRIBUTES @CLASS_ATTRIBUTES
18 %SYNONYMS %DEFAULTS);
19 @AUTO_ATTRIBUTES=qw(first_name last_name sex friends);
20 @OTHER_ATTRIBUTES=qw(full_name);
21 @CLASS_ATTRIBUTES=qw(count);
22 %DEFAULTS=(friends=>[]);
23 %SYNONYMS=(gender=>'sex',name=>'full_name');
24 Class::AutoClass::declare;
25
26 # method to perform non-standard initialization, if any
27 sub _init_self {
28 my ($self,$class,$args) = @_;
29 return unless $class eq __PACKAGE__;
30 # any non-standard initialization goes here
31 $self->count($self->count + 1); # increment number of objects created
32 }
33
34 # implementation of non-automatic attribute 'full_name'
35 # computed from first_name and last_name
36 sub full_name {
37 my $self=shift;
38 if (@_) { # to set full_name, have to set first & last
39 my $full_name=shift;
40 my($first_name,$last_name)=split(/\s+/,$full_name);
41 $self->first_name($first_name);
42 $self->last_name($last_name);
43 }
44 return join(' ',$self->first_name,$self->last_name);
45 }
46
47 ########################################
48 # code that uses class
49 #
50 use Person;
51 my $john=new Person(name=>'John Smith',sex=>'M');
52 my $first_name=$john->first_name; # 'John'
53 my $gender=$john->gender; # 'M'
54 my $friends=$john->friends; # []
55 $john->last_name('Doe'); # set last_name
56 my $name=$john->name; # 'John Doe'
57 my $count=$john->count; # 1
58
60 This is yet another module that generates standard 'get' and 'set'
61 methods for Perl classes. It also handles initialization of object and
62 class data from parameter lists or defaults, and arranges for object
63 creation and initialization to occur in top-down, textbook order even
64 in the presence of multiple inheritance.
65
66 CAUTION: This module is old. We use it internally, and while it works
67 well for our purposes, we urge new users to heed the warnings in "BUGS"
68 and to look at other modules listed in "SEE ALSO". This release brings
69 the CPAN version of the module up-to-date relative to our internal
70 version, something we should have done long ago. We do not expect
71 further releases of this code base, except for bug fixes. Future
72 development, if any, will entail a redesign building on newer CPAN
73 modules.
74
75 Defining the class
76 We use the term "attribute" for object and class variables being
77 managed by this module. This was appropriate usage when we wrote the
78 code several years ago, but we recognize that "attribute" now means
79 something else in Perl-dom. It's too late for us to change. Sorry.
80
81 Class::AutoClass provides a number of variables for specifying
82 attributes and default values.
83
84 @AUTO_ATTRIBUTES is a list of attribute names. The software generates
85 'get' and 'set' methods for each attribute. By default, the name of
86 the method is identical to the attribute (but see $CASE below). Values
87 of attributes can be set via the 'new' constructor, %DEFAULTS, or the
88 'set' method as discussed below.
89
90 @OTHER_ATTRIBUTES is a list of attributes for which 'get' and 'set'
91 methods are NOT generated, but whose values can be set via the 'new'
92 constructor or the 'set' method as discussed below.
93
94 @CLASS_ATTRIBUTES is a list of class attributes. The module generates
95 'get' and 'set' methods for each attribute just as for
96 @AUTO_ATTRIBUTES. Values of attributes can be set via the 'new'
97 constructor, %DEFAULTS (initialized when the 'declare' function is
98 called), or the 'set' method as discussed below. Normal inheritance
99 rules apply to class attributes (but instances of the same class share
100 the same class variable).
101
102 %SYNONYMS is a hash that defines synonyms for attributes. Each entry is
103 of the form 'new_attribute_name'=>'old_attribute_name'. 'get' and 'set'
104 methods are generated for the new names; these methods simply call the
105 methods for the old name.
106
107 %DEFAULTS is a hash that defines default values for attributes. Each
108 entry is of the form 'attribute_name'=>'default_value'.
109
110 $CASE controls whether additional methods are generated with all upper
111 or all lower case names. It should be a string containing the strings
112 'upper' or 'lower' (case insensitive) if the desired case is desired.
113 [BUG: This is hopelessly broken and ill-conceived. Most of the code
114 assumes that attributes are lower case. Even when upper or mixed case
115 methods are present, the attribute setting code ignores them.]
116
117 The 'declare' function actually generates the methods. This should be
118 called once in the main code of the class after the variables described
119 above are set.
120
121 Class::AutoClass must be the first class in @ISA or 'use base'!! As
122 usual, you create objects by calling 'new'. Since Class::AutoClass is
123 the first class in @ISA, its 'new' method is the one that's called.
124 Class::AutoClass's 'new' examines the rest of @ISA looking for a
125 superclass capable of creating the object. If no such superclass is
126 found, Class::AutoClass creates the object itself. Once the object is
127 created, Class::AutoClass arranges to have all subclasses run their
128 initialization methods (_init_self) in a top-down order.
129
130 Object creation and initialization
131 We expect objects to be created by invoking 'new' on its class. For
132 example
133
134 $john=new Person(first_name=>'John',last_name=>'Smith')
135
136 To correctly initialize objects that participate in multiple
137 inheritance, we use a technique described in Chapter 10 of Paul
138 Fenwick's tutorial on Object Oriented Perl
139 <http://perltraining.com.au/notes/perloo.pdf>. (We experimented with
140 Damian Conway's NEXT pseudo-pseudo-class but could not get it to
141 traverse the inheritance structure in the desired top-down order; this
142 may be fixed in recent versions. See "SEE ALSO" for other modules
143 addressing this issue.)
144
145 Class::AutoClass provides a 'new' method that expects a keyword
146 argument list. It converts the argument list into a
147 Hash::AutoHash::Args object, which normalizes the keywords to ignore
148 case and leading dashes. 'new' then initializes all attributes using
149 the arguments and default values in %DEFAULTS. This works for
150 synonyms, too, of course.
151
152 CAUTION: If you supply a default value for both a synonym and its
153 target, the one that sticks is arbitrary. Likewise if you supply an
154 initial value for both a synonym and its target, the one that sticks is
155 arbitrary.
156
157 Initialization of attributes is done for all classes in the object's
158 class structure at the same time. If a given attribute is defined
159 multiple times, the most specific definition wins. This is only an
160 issue if the attribute is defined differently in different classes, eg,
161 as an 'auto' attribute in one class and an 'other' attribute, class
162 atribute, or synonym in another.
163
164 Class::AutoClass::new initializes attributes by calling the 'set'
165 methods for these elements with the like-named parameter or default.
166 For 'other' attributes, the class writer can implement non-standard
167 initialization within the 'set' method.
168
169 The class writer can provide an _init_self method for any classes
170 requiring additional initialization. 'new' calls _init_self after
171 initializing all attributes for all classes in the object's class
172 structure.
173
174 The _init_self method is responsible for initializing just the "current
175 level" of the object, not its superclasses. 'new' calls _init_self for
176 each class in the class hierarchy from top to bottom, being careful to
177 call the method exactly once per class even in the presence of multiple
178 inheritance. The _init_self method should not call SUPER::_init_self
179 as this would cause redundant initialization of superclasses.
180
181 Subclasses of Class::AutoClass do not usually need their own 'new'
182 methods. The main exception is a subclass whose 'new' allows
183 positional arguments. In this case, the subclass 'new' is responsible
184 for converting the positional arguments into keyword=>value form. At
185 this point, the method should call Class::AutoClass::new with the
186 converted argument list. In most cases, the subclass should not call
187 SUPER::new as this would force redundant argument processing in any
188 superclass that also has a 'new' method.
189
190 Traps for the unwary
191 Two aspects of object initialization seem particularly troublesome,
192 causing subtle bugs and ensuing grief.
193
194 One trap is that attribute-initialization occurs in arbitrary order.
195 There is a temptation when writing 'set' methods to assume that
196 attributes are initialized in the natural order that you would set them
197 if you were writing the initialization code yourself. I have been
198 burned by this many times. This is mainly an issue for
199 OTHER_ATTRIBUTES. The issue also arises with SYNONYMS. If your code
200 initializes both sides of a synonym with different values, it is
201 undefined which value will stick. This can happen when your codes sets
202 values explicitly or via DEFAULTS.
203
204 The second trap involves "method resolution", ie, the way Perl chooses
205 which sub to call when you invoke a method. Consider a class hierarchy
206 "A-B" with "A" at the top, and imagine that each class defines a method
207 "f". Invoking "f" on an object of class "A" will call the code in
208 class "A", whereas invoking "f" on an object of class "B" will call the
209 code in "A". No surprise yet.
210
211 Now suppose the object initialization code for "A" calls "f" and think
212 about what will happen when creating an object of class "B". Invoking
213 "f" on this object will call the version of "f" in "B", which means we
214 will be running code that may depend on the initialization of "B" which
215 hasn't happened yet!
216
217 This gotcha can arise in a fairly obvious way if the call to "f" is in
218 the _init_self method. It can arise more subtly if the call is in the
219 'set' method of an OTHER_ATTRIBUTE. It can arise even more subtly if
220 "f" is an AUTO_ATTRIBUTE in one class and a CLASS_ATTRIBUTE in the
221 other. The opportunity for mischief multiplies when SYNONYMS are
222 involved.
223
225 declare
226 Title : declare
227 Usage : Class::AutoClass::declare;
228 Function: Setup Class::AutoClass machinery for a class
229 Returns : nothing
230 Args : Optional name of class being created; default is __PACKAGE__
231 Note : Uses current values of @AUTO_ATTRIBUTES, @OTHER_ATTRIBUTES,
232 @CLASS_ATTRIBUTES, %SYNONYMS, %DEFAULTS, $CASE.
233
234 _init_self
235 Title : _init_self
236 Usage : $self->_init_self($class,$args)
237 Function: Called by 'new' to initialize new object
238 Returns : nothing
239 Args : class being initialized and Hash::AutoHash::Args object
240 Notes : Implemented by subclasses requiring non-standard initialization. Not
241 implemented by Class::AutoClass itself
242
243 The original design of Class::AutoClass provided no way for _init_self
244 to control the return-value of 'new'. All _init_self could do was
245 modify the contents of the object already constructed by 'new'. This
246 proved too limiting, and we added two workarounds: (1) If _init_self
247 sets the __NULLIFY__ element of the object to a true value (eg, by
248 saying $self->{__NULLIFY__}=1), 'new' will return undef. (2) If
249 _init_self sets the __OVERRIDE__ element of the object to true value
250 (usually an object), 'new' will return that value. If both __NULLIFY__
251 and __OVERRIDE__ are set, it is arbitrary which one will win.
252
254 new
255 Title : new
256 Usage : $john=new Person(first_name=>'John',last_name=>'Smith')
257 where Person is a subclass of Class::AutoClass
258 Function: Create and initialize object
259 Returns : New object of the given class or undef
260 Args : Any arguments needed by the class in keyword=>value form
261 Notes : Implemented by Class::AutoClass and usually not by subclasses
262
263 set
264 Title : set
265 Usage : $john->set(last_name=>'Doe',sex=>'M')
266 Function: Set multiple attributes in existing object
267 Args : Parameter list in same format as for new
268 Returns : nothing
269
270 set_attributes
271 Title : set_attributes
272 Usage : $john->set_attributes([qw(first_name last_name)],$args)
273 Function: Set multiple attributes from a Hash::AutoHash::Args object
274 Any attribute value that is present in $args is set
275 Args : ARRAY ref of attributes
276 Hash::AutoHash::Args object
277 Returns : nothing
278
279 get
280 Title : get
281 Usage : ($first,$last)=$john->get(qw(first_name last_name))
282 Function: Get values for multiple attributes
283 Args : Attribute names
284 Returns : List of attribute values
285
287 mro, Compat::MRO, and Class::C3 deal with "method resolution order" and
288 may offer better ways to control the order in which class
289 initialization occurs. NEXT is an older approach still in use.
290
291 CPAN has many modules that generate 'get' and 'set' methods including
292 Class::Accessor, Class::Builer, Class::Class, Class::Frame,
293 Class::Generate, Class::MethodMaker, Class::Struct.
294
295 This class uses Hash::AutoHash::Args to represent keyword=>value
296 argument lists.
297
299 Nat Goodman, "<natg at shore.net>"
300
302 Please report any bugs or feature requests to "bug-class-autoclass at
303 rt.cpan.org", or through the web interface at
304 <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Class-AutoClass>. I
305 will be notified, and then you'll automatically be notified of progress
306 on your bug as I make changes.
307
308 Known Bugs and Caveats
309 1. This module is old
310 The current code does not build on recent CPAN modules that cover
311 much of the same ground. Future releases, if any, will entail a
312 redesign.
313
314 2. Inheriting 'new' from an external class often fails
315 We intended to support class hierarchies containing "external"
316 classes, ie, ones that are not derived from Class::AutoClass. A use-
317 case we really wanted to handle was letting an external class
318 construct the object by running its 'new' method. The code tries to
319 do this, but it doesn't work in most cases, because we provided no
320 way to manipulate the arguments that are sent to the external class's
321 'new' method. So, for example, if the external 'new' expects a
322 positional argument list, you're hosed.
323
324 3. Non-lower case attribute names don't work well
325 The design is schizophrenic in its treatment of attribute case. We
326 process argument lists using Hash::AutoHash::Args, which explicitly
327 converts all keywords to lower-case. Yet we provide the $CASE
328 variable which is supposed to control attribute case conversion.
329 What were we thinking??
330
331 Lower-case attribute names are the only ones that work well.
332
333 4. The workarounds that let _init_self control the value returned by
334 'new' are crude.
335 5. Accessing class attributes sometimes fails when a parent class
336 "uses" its children.
337 This happens rarely, but can occur legitimately, e.g., when a base
338 class dispatches to a child based on the value of a parameter. The
339 issue arises only if the parent class uses its children at compile-
340 time (typically by including them in the list of uses at the top of
341 the module); run-time uses or requires don't seem to be a problem.
342
343 A workaround is implemented that handles such cases "most of the
344 time". The case that is not fully handled arises when a
345 Class::AutoClass class inherits from a non-Class::AutoClass class. In
346 this case, declaration of the class is deferred until run-time, more
347 specifically until the first time 'new' is called for the class or a
348 subclass. This works fine except for class attributes, since class
349 attributes (unlike instance attributes) can be accessed before 'new'
350 is called. To be clear, in this one case, it does not work to access
351 class attributes before creating an object of the class - this is
352 clearly a bug.
353
354 6. No special support for DESTROY
355 Object destruction should occur bottom-to-top, opposite to the
356 direction of object initialization. Making this happen is a
357 challenge in the presence of multiple inheritance. Class::AutoClass
358 does nothing to help.
359
360 7. Subtle bugs in object initialization
361 See "Traps for the unwary".
362
363 8. Initialization of synonyms
364 It works fine to provide a default value for a synonym (via
365 %DEFAULTS), but if you supply a default value for both a synonym and
366 its target, the one that sticks is arbitrary. Likewise it works fine
367 to provide an initial value for a synonym (via 'new'), but if you
368 supply an initial value for both a synonym and its target, the one
369 that sticks is arbitrary.
370
371 9. Inconsistent attribute declarations
372 Inconsistent attribute declarations are not detected in all cases.
373 The code successfully detects cases where an attribute is defined as
374 a class attribute in one class, and an instance attribute ('auto' or
375 'other') in a superclass or subclass. It does not reliably detect
376 inconsistencies that occur in a single class. The following cases
377 are not detected:
378
379 - attribute declared 'auto' and 'other'
380 - attribute declared 'auto' and 'class'
381 - attribute declared 'other' and 'class' when no implementation is
382 provided for 'other'
383 - attribute declared 'synonym' and 'other'
384
386 You can find documentation for this module with the perldoc command.
387
388 perldoc Class::AutoClass
389
390 You can also look for information at:
391
392 • RT: CPAN's request tracker
393
394 <http://rt.cpan.org/NoAuth/Bugs.html?Dist=Class-AutoClass>
395
396 • AnnoCPAN: Annotated CPAN documentation
397
398 <http://annocpan.org/dist/Class-AutoClass>
399
400 • CPAN Ratings
401
402 <http://cpanratings.perl.org/d/Class-AutoClass>
403
404 • Search CPAN
405
406 <http://search.cpan.org/dist/Class-AutoClass/>
407
409 Chris Cavnor maintained the CPAN version of the module for several
410 years after its initial release.
411
413 Copyright 2003, 2009 Nat Goodman, Institute for Systems Biology (ISB).
414 All Rights Reserved.
415
416 This program is free software; you can redistribute it and/or modify it
417 under the terms of either: the GNU General Public License as published
418 by the Free Software Foundation; or the Artistic License.
419
420 See http://dev.perl.org/licenses/ for more information.
421
422
423
424perl v5.34.0 2021-07-22 Class::AutoClass(3)