Class::AutoClass(3pm)
π Class::AutoClass(3pm) π
okay bestie, this is the Class::AutoClass(3pm) page from the User Contributed Perl Documentation collection. it's giving old-school Perl magic, and we're about to unpack it together. π β¨
β¨ NAME β¨
Class::AutoClass β Create get and set methods and simplify object initialization. π
πΈ VERSION πΈ
Version 1.56
π¦ SYNOPSIS π¦
# code that defines class
#
package Person;
use base qw(Class::AutoClass);
use vars qw(@AUTO_ATTRIBUTES @OTHER_ATTRIBUTES @CLASS_ATTRIBUTES
%SYNONYMS %DEFAULTS);
@AUTO_ATTRIBUTES=qw(first_name last_name sex friends);
@OTHER_ATTRIBUTES=qw(full_name);
@CLASS_ATTRIBUTES=qw(count);
%DEFAULTS=(friends=>[]);
%SYNONYMS=(gender=>'sex',name=>'full_name');
Class::AutoClass::declare;
# method to perform non-standard initialization, if any
sub _init_self {
my ($self,$class,$args) = @_;
return unless $class eq __PACKAGE__;
# any non-standard initialization goes here
$self->count($self->count + 1); # increment number of objects created
}
# implementation of non-automatic attribute 'full_name'
# computed from first_name and last_name
sub full_name {
my $self=shift;
if (@_) { # to set full_name, have to set first & last
my $full_name=shift;
my($first_name,$last_name)=split(/\s+/,$full_name);
$self->first_name($first_name);
$self->last_name($last_name);
}
return join(' ',$self->first_name,$self->last_name);
}
########################################
# code that uses class
#
use Person;
my $john=new Person(name=>'John Smith',sex=>'M');
my $first_name=$john->first_name; # 'John'
my $gender=$john->gender; # 'M'
my $friends=$john->friends; # []
$john->last_name('Doe'); # set last_name
my $name=$john->name; # 'John Doe'
my $count=$john->count; # 1
π DESCRIPTION π
so this is yet another module that generates the standard get and set methods for Perl classes. it also handles initialization of object and class data from parameter lists or defaults, and it arranges for object creation and initialization to happen in top-down, textbook order β even when multiple inheritance is in the picture. π
β οΈ CAUTION: This module is old. We use it internally, and while it works well for our purposes, we urge new users to heed the warnings in "BUGS" and to look at other modules listed in "SEE ALSO". This release brings the CPAN version of the module up-to-date relative to our internal version, something we should have done long ago. We do not expect further releases of this code base, except for bug fixes. Future development, if any, will entail a redesign building on newer CPAN modules.
π Defining the class π
we use the term "attribute" for object and class variables being managed by this module. that was appropriate usage when we wrote the code several years ago, but we recognize that "attribute" now means something else in Perl-dom. it's too late for us to change. sorry. π
Class::AutoClass provides a number of variables for specifying attributes and default values.
@AUTO_ATTRIBUTESβ is a list of attribute names. The software generatesgetandsetmethods for each attribute. By default, the name of the method is identical to the attribute (but see$CASEbelow). Values of attributes can be set via thenewconstructor,%DEFAULTS, or thesetmethod as discussed below.@OTHER_ATTRIBUTESβ is a list of attributes for whichgetandsetmethods are NOT generated, but whose values can be set via thenewconstructor or thesetmethod as discussed below.@CLASS_ATTRIBUTESβ is a list of class attributes. The module generatesgetandsetmethods for each attribute just as for@AUTO_ATTRIBUTES. Values of attributes can be set via thenewconstructor,%DEFAULTS(initialized when thedeclarefunction is called), or thesetmethod as discussed below. Normal inheritance rules apply to class attributes (but instances of the same class share the same class variable).%SYNONYMSβ is a hash that defines synonyms for attributes. Each entry is of the form'new_attribute_name'=>'old_attribute_name'.getandsetmethods are generated for the new names; these methods simply call the methods for the old name.%DEFAULTSβ is a hash that defines default values for attributes. Each entry is of the form'attribute_name'=>'default_value'.$CASEβ controls whether additional methods are generated with all upper or all lower case names. It should be a string containing the strings'upper'or'lower'(case insensitive) if the desired case is desired. [BUG: This is hopelessly broken and ill-conceived. Most of the code assumes that attributes are lower case. Even when upper or mixed case methods are present, the attribute setting code ignores them.]
the declare function actually generates the methods. This should be called once in the main code of the class after the variables described above are set.
β οΈClass::AutoClassmust be the first class in@ISAoruse base!! As usual, you create objects by callingnew. SinceClass::AutoClassis the first class in@ISA, itsnewmethod is the one that's called.Class::AutoClass'snewexamines the rest of@ISAlooking for a superclass capable of creating the object. If no such superclass is found,Class::AutoClasscreates the object itself. Once the object is created,Class::AutoClassarranges to have all subclasses run their initialization methods (_init_self) in a top-down order.
β¨ Object creation and initialization β¨
we expect objects to be created by invoking new on its class. For example
$john=new Person(first_name=>'John',last_name=>'Smith')
to correctly initialize objects that participate in multiple inheritance, we use a technique described in Chapter 10 of Paul Fenwick's tutorial on Object Oriented Perl <http://perltraining.com.au/notes/perloo.pdf>. (We experimented with Damian Conway's NEXT pseudo-pseudo-class but could not get it to traverse the inheritance structure in the desired top-down order; this may be fixed in recent versions. See "SEE ALSO" for other modules addressing this issue.)
Class::AutoClass provides a new method that expects a keyword argument list. It converts the argument list into a Hash::AutoHash::Args object, which normalizes the keywords to ignore case and leading dashes. new then initializes all attributes using the arguments and default values in %DEFAULTS. This works for synonyms, too, of course.
β οΈ CAUTION: If you supply a default value for both a synonym and its target, the one that sticks is arbitrary. Likewise if you supply an initial value for both a synonym and its target, the one that sticks is arbitrary.
initialization of attributes is done for all classes in the object's class structure at the same time. If a given attribute is defined multiple times, the most specific definition wins. This is only an issue if the attribute is defined differently in different classes, eg, as an auto attribute in one class and an other attribute, class atribute, or synonym in another.
Class::AutoClass::new initializes attributes by calling the set methods for these elements with the like-named parameter or default. For other attributes, the class writer can implement non-standard initialization within the set method.
the class writer can provide an _init_self method for any classes requiring additional initialization. new calls _init_self after initializing all attributes for all classes in the object's class structure.
the _init_self method is responsible for initializing just the "current level" of the object, not its superclasses. new calls _init_self for each class in the class hierarchy from top to bottom, being careful to call the method exactly once per class even in the presence of multiple inheritance. The _init_self method should not call SUPER::_init_self as this would cause redundant initialization of superclasses.
subclasses of Class::AutoClass do not usually need their own new methods. The main exception is a subclass whose new allows positional arguments. In this case, the subclass new is responsible for converting the positional arguments into keyword=>value form. At this point, the method should call Class::AutoClass::new with the converted argument list. In most cases, the subclass should not call SUPER::new as this would force redundant argument processing in any superclass that also has a new method.
π Traps for the unwary π
two aspects of object initialization seem particularly troublesome, causing subtle bugs and ensuing grief. π
one trap is that attribute-initialization occurs in arbitrary order. There is a temptation when writing set methods to assume that attributes are initialized in the natural order that you would set them if you were writing the initialization code yourself. I have been burned by this many times. This is mainly an issue for OTHER_ATTRIBUTES. The issue also arises with SYNONYMS. If your code initializes both sides of a synonym with different values, it is undefined which value will stick. This can happen when your codes sets values explicitly or via DEFAULTS.
the second trap involves "method resolution", ie, the way Perl chooses which sub to call when you invoke a method. Consider a class hierarchy "A-B" with "A" at the top, and imagine that each class defines a method "f". Invoking "f" on an object of class "A" will call the code in class "A", whereas invoking "f" on an object of class "B" will call the code in "A". No surprise yet.
now suppose the object initialization code for "A" calls "f" and think about what will happen when creating an object of class "B". Invoking "f" on this object will call the version of "f" in "B", which means we will be running code that may depend on the initialization of "B" which hasn't happened yet!
this gotcha can arise in a fairly obvious way if the call to "f" is in the _init_self method. It can arise more subtly if the call is in the set method of an OTHER_ATTRIBUTE. It can arise even more subtly if "f" is an AUTO_ATTRIBUTE in one class and a CLASS_ATTRIBUTE in the other. The opportunity for mischief multiplies when SYNONYMS are involved.
β¨ METHODS AND FUNCTIONS FOR CLASS DEVELOPERS β¨
declare
- Title:
declare - Usage:
Class::AutoClass::declare; - Function: Setup Class::AutoClass machinery for a class
- Returns: nothing
- Args: Optional name of class being created; default is
__PACKAGE__ - Note: Uses current values of
@AUTO_ATTRIBUTES,@OTHER_ATTRIBUTES,@CLASS_ATTRIBUTES,%SYNONYMS,%DEFAULTS,$CASE.
_init_self
- Title:
_init_self - Usage:
$self->_init_self($class,$args) - Function: Called by
'new'to initialize new object - Returns: nothing
- Args: class being initialized and
Hash::AutoHash::Argsobject - Notes: Implemented by subclasses requiring non-standard initialization. Not implemented by
Class::AutoClassitself
The original design of Class::AutoClass provided no way for _init_self to control the return-value of 'new'. All _init_self could do was modify the contents of the object already constructed by 'new'. This proved too limiting, and we added two workarounds: (1) If _init_self sets the __NULLIFY__ element of the object to a true value (eg, by saying $self->{__NULLIFY__}=1), 'new' will return undef. (2) If _init_self sets the __OVERRIDE__ element of the object to true value (usually an object), 'new' will return that value. If both __NULLIFY__ and __OVERRIDE__ are set, it is arbitrary which one will win.
π METHODS AND FUNCTIONS FOR CLASS USERS π
new
- Title:
new - Usage:
$john=new Person(first_name=>'John',last_name=>'Smith')
where Person is a subclass of Class::AutoClass
- Function: Create and initialize object
- Returns: New object of the given class or
undef - Args: Any arguments needed by the class in
keyword=>valueform - Notes: Implemented by
Class::AutoClassand usually not by subclasses
set
- Title:
set - Usage:
$john->set(last_name=>'Doe',sex=>'M') - Function: Set multiple attributes in existing object
- Args: Parameter list in same format as for
new - Returns: nothing
set_attributes
- Title:
set_attributes - Usage:
$john->set_attributes([qw(first_name last_name)],$args) - Function: Set multiple attributes from a
Hash::AutoHash::Argsobject. Any attribute value that is present in$argsis set - Args: ARRAY ref of attributes;
Hash::AutoHash::Argsobject - Returns: nothing
get
- Title:
get - Usage:
($first,$last)=$john->get(qw(first_name last_name)) - Function: Get values for multiple attributes
- Args: Attribute names
- Returns: List of attribute values
π SEE ALSO π
mro, Compat::MRO, and Class::C3 deal with "method resolution order" and may offer better ways to control the order in which class initialization occurs. NEXT is an older approach still in use.
CPAN has many modules that generate 'get' and 'set' methods including Class::Accessor, Class::Builer, Class::Class, Class::Frame, Class::Generate, Class::MethodMaker, Class::Struct.
This class uses Hash::AutoHash::Args to represent keyword=>value argument lists.
π©βπ» AUTHOR π©βπ»
Nat Goodman, "<natg at shore.net>"
π BUGS AND CAVEATS π
Please report any bugs or feature requests to "bug-class-autoclass at rt.cpan.org", or through the web interface at <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Class-AutoClass>. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
Known Bugs and Caveats
- This module is old The current code does not build on recent CPAN modules that cover much of the same ground. Future releases, if any, will entail a redesign.
- Inheriting
'new'from an external class often fails We intended to support class hierarchies containing "external" classes, ie, ones that are not derived fromClass::AutoClass. A use-case we really wanted to handle was letting an external class construct the object by running its'new'method. The code tries to do this, but it doesn't work in most cases, because we provided no way to manipulate the arguments that are sent to the external class's'new'method. So, for example, if the external'new'expects a positional argument list, you're hosed. - Non-lower case attribute names don't work well The design is schizophrenic in its treatment of attribute case. We process argument lists using
Hash::AutoHash::Args, which explicitly converts all keywords to lower-case. Yet we provide the$CASEvariable which is supposed to control attribute case conversion. What were we thinking?? Lower-case attribute names are the only ones that work well. - The workarounds that let
_init_selfcontrol the value returned by'new'are crude. - Accessing class attributes sometimes fails when a parent class "uses" its children This happens rarely, but can occur legitimately, e.g., when a base class dispatches to a child based on the value of a parameter. The issue arises only if the parent class uses its children at compile-time (typically by including them in the list of uses at the top of the module); run-time uses or requires don't seem to be a problem. A workaround is implemented that handles such cases "most of the time". The case that is not fully handled arises when a
Class::AutoClassclass inherits from a non-Class::AutoClassclass. In this case, declaration of the class is deferred until run-time, more specifically until the first time'new'is called for the class or a subclass. This works fine except for class attributes, since class attributes (unlike instance attributes) can be accessed before'new'is called. To be clear, in this one case, it does not work to access class attributes before creating an object of the class β this is clearly a bug. - No special support for
DESTROYObject destruction should occur bottom-to-top, opposite to the direction of object initialization. Making this happen is a challenge in the presence of multiple inheritance.Class::AutoClassdoes nothing to help. - Subtle bugs in object initialization See "Traps for the unwary".
- Initialization of synonyms It works fine to provide a default value for a synonym (via
%DEFAULTS), but if you supply a default value for both a synonym and its target, the one that sticks is arbitrary. Likewise it works fine to provide an initial value for a synonym (via'new'), but if you supply an initial value for both a synonym and its target, the one that sticks is arbitrary. - Inconsistent attribute declarations Inconsistent attribute declarations are not detected in all cases. The code successfully detects cases where an attribute is defined as a class attribute in one class, and an instance attribute (
'auto'or'other') in a superclass or subclass. It does not reliably detect inconsistencies that occur in a single class. The following cases are not detected:- attribute declared
'auto'and'other' - attribute declared
'auto'and'class' - attribute declared
'other'and'class'when no implementation is provided for'other' - attribute declared
'synonym'and'other'
- attribute declared
π SUPPORT π
You can find documentation for this module with the perldoc command.
perldoc Class::AutoClass
You can also look for information at:
- RT: CPAN's request tracker
<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Class-AutoClass> - AnnoCPAN: Annotated CPAN documentation
<http://annocpan.org/dist/Class-AutoClass> - CPAN Ratings
<http://cpanratings.perl.org/d/Class-AutoClass> - Search CPAN
<http://search.cpan.org/dist/Class-AutoClass/>
π ACKNOWLEDGEMENTS π
Chris Cavnor maintained the CPAN version of the module for several years after its initial release.
π COPYRIGHT & LICENSE π
Copyright 2003, 2009 Nat Goodman, Institute for Systems Biology (ISB). All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.
okay bestie, that's the whole vibe π this page came from perl v5.42.0, dated 2025-07-25, and it's the Class::AutoClass(3pm) manual β go forth and autoclass responsibly π«Άβ¨
π¦ where this page comes from
- fedora 43: perl-Class-AutoClass 1.56-20.fc43 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms