1Class::AutoClass(3)   User Contributed Perl Documentation  Class::AutoClass(3)
2
3
4

NAME

6       Class::AutoClass - Create get and set methods and simplify object
7       initialization
8

VERSION

10       Version 1.56
11

SYNOPSIS

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

DESCRIPTION

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

METHODS AND FUNCTIONS FOR CLASS DEVELOPERS

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

METHODS AND FUNCTIONS FOR CLASS USERS

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

SEE ALSO

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

AUTHOR

299       Nat Goodman, "<natg at shore.net>"
300

BUGS AND CAVEATS

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

SUPPORT

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

ACKNOWLEDGEMENTS

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)
Impressum