Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
Class::AutoClass(3)   User Contributed Perl Documentation  Class::AutoClass(3)

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
       This is yet another module that generates standard 'get'	and 'set'
       methods for Perl	classes.  It also handles initialization of object and
       class data from parameter lists or defaults, and	arranges for object
       creation	and initialization to occur in top-down, textbook order	even
       in the presence of multiple inheritance.

       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.	This 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 generates
       'get' and 'set' methods for each	attribute.  By default,	the name of
       the method is identical to the attribute	(but see $CASE below). Values
       of attributes can be set	via the	'new' constructor, %DEFAULTS, or the
       'set' method as discussed below.

       @OTHER_ATTRIBUTES is a list of attributes for which 'get' and 'set'
       methods are NOT generated, but whose values can be set via the 'new'
       constructor or the 'set'	method as discussed below.

       @CLASS_ATTRIBUTES is a list of class attributes.	 The module generates
       'get' and 'set' methods for each	attribute just as for
       @AUTO_ATTRIBUTES.  Values of attributes can be set via the 'new'
       constructor, %DEFAULTS (initialized when	the 'declare' function is
       called),	or the 'set' method 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'. 'get' and 'set'
       methods 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::AutoClass	must be	the first class	in @ISA	or 'use	base'!!	As
       usual, you create objects by calling 'new'. Since Class::AutoClass is
       the first class in @ISA,	its 'new' method is the	one that's called.
       Class::AutoClass's 'new'	examines the rest of @ISA looking for a
       superclass capable of creating the object.  If no such superclass is
       found, Class::AutoClass creates the object itself.  Once	the object is
       created,	Class::AutoClass arranges 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::Args object
	Notes	: Implemented by subclasses requiring non-standard initialization. Not
		  implemented by Class::AutoClass itself

       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=>value form
	Notes	: Implemented by Class::AutoClass and 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::Args object
		  Any attribute	value that is present in $args is set
	Args	: ARRAY	ref of attributes
		  Hash::AutoHash::Args object
	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
       1. 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.

       2. Inheriting 'new' from	an external class often	fails
	 We intended to	support	class hierarchies containing "external"
	 classes, ie, ones that	are not	derived	from Class::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.

       3. 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 $CASE
	 variable which	is supposed to control attribute case conversion.
	 What were we thinking??

	 Lower-case attribute names are	the only ones that work	well.

       4. The workarounds that let _init_self control the value	returned by
       'new' are crude.
       5. 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::AutoClass class	inherits from a	non-Class::AutoClass class. 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.

       6. No special support for DESTROY
	 Object	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::AutoClass
	 does nothing to help.

       7. Subtle bugs in object	initialization
	 See "Traps for	the unwary".

       8.  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.

       9.  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'

SUPPORT
       You can find documentation for this module with the perldoc command.

	   perldoc Class::AutoClass

       You can also look for information at:

       o   RT: CPAN's request tracker

	   <http://rt.cpan.org/NoAuth/Bugs.html?Dist=Class-AutoClass>

       o   AnnoCPAN: Annotated CPAN documentation

	   <http://annocpan.org/dist/Class-AutoClass>

       o   CPAN	Ratings

	   <http://cpanratings.perl.org/d/Class-AutoClass>

       o   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.

perl v5.24.1			  2017-07-03		   Class::AutoClass(3)

NAME | VERSION | SYNOPSIS | DESCRIPTION | METHODS AND FUNCTIONS FOR CLASS DEVELOPERS | METHODS AND FUNCTIONS FOR CLASS USERS | SEE ALSO | AUTHOR | BUGS AND CAVEATS | SUPPORT | ACKNOWLEDGEMENTS | COPYRIGHT & LICENSE

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=Class::AutoClass&sektion=3&manpath=FreeBSD+12.0-RELEASE+and+Ports>

home | help