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

FreeBSD Manual Pages

  
 
  

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

NAME
       Class::Std - Support for	creating standard "inside-out" classes

VERSION
       This document describes Class::Std version 0.013

SYNOPSIS
	   package MyClass;
	   use Class::Std;

	   # Create storage for	object attributes...
	   my %name : ATTR;
	   my %rank : ATTR;
	   my %snum : ATTR;

	   my %public_data : ATTR;

	   # Handle initialization of objects of this class...
	   sub BUILD {
	       my ($self, $obj_ID, $arg_ref) = @_;

	       $name{$obj_ID} =	check_name( $arg_ref->{name} );
	       $rank{$obj_ID} =	check_rank( $arg_ref->{rank} );
	       $snum{$obj_ID} =	_gen_uniq_serial_num();
	   }

	   # Handle cleanup of objects of this class...
	   sub DEMOLISH	{
	       my ($self, $obj_ID) = @_;

	       _recycle_serial_num( $snum{$obj_ID} );
	   }

	   # Handle unknown method calls...
	   sub AUTOMETHOD {
	       my ($self, $obj_ID, @other_args)	= @_;

	       # Return	any public data...
	       if ( m/\A get_(.*)/ ) {	# Method name passed in	$_
		   my $get_what	= $1;
		   return sub {
		       return $public_data{$obj_ID}{$get_what};
		   }
	       }

	       warn "Can't call	$method_name on	", ref $self, "	object";

	       return;	 # The call is declined	by not returning a sub ref
	   }

DESCRIPTION
       This module provides tools that help to implement the "inside out
       object" class structure in a convenient and standard way.

       Portions	of the following code and documentation	from "Perl Best
       Practices" copyright (c)	2005 by	O'Reilly Media,	Inc. and reprinted
       with permission.

   Introduction
       Most programmers	who use	Perl's object-oriented features	construct
       their objects by	blessing a hash. But, in doing so, they	undermine the
       robustness of the OO approach. Hash-based objects are unencapsulated:
       their entries are open for the world to access and modify.

       Objects without effective encapsulation are vulnerable. Instead of
       politely	respecting their public	interface, some	clever client coder
       inevitably will realize that it's marginally faster to interact
       directly	with the underlying implementation, pulling out	attribute
       values directly from the	hash of	an object:

	   for my $file	( get_file_objs() ) {
	       print $file->{name}, "\n";
	   }

       instead of using	the official interface:

	   for my $file	( get_file_objs() ) {
	       print $file->get_name(),	"\n";
	   }

       From the	moment someone does that, your class is	no longer cleanly
       decoupled from the code that uses it. You can't be sure that any	bugs
       in your class are actually caused by the	internals of your class, and
       not the result of some kind of monkeying	by the client code. And	to
       make matters worse, now you can't ever change those internals without
       the risk	of breaking some other part of the system.

       There is	a simple, convenient, and utterly secure way to	prevent	client
       code from accessing the internals of the	objects	you provide. Happily,
       that approach also guards against misspelling attribute names (a	common
       error in	hash-based classes), as	well as	being just as fast as--and
       often more memory-efficient than--ordinary hash-based objects.

       That approach is	referred to by various names--flyweight	scalars,
       warehoused attributes, inverted indices--but most commonly it's known
       as: inside-out objects. Consider	the following class definitions:

	   package File::Hierarchy;
	   {
	       # Objects of this class have the	following attributes...
	       my %root_of;   #	The root directory of the file hierarchy
	       my %files_of;  #	Array storing object for each file in root directory

	       # Constructor takes path	of file	system root directory...
	       sub new {
		   my ($class, $root) =	@_;

		   # Bless a scalar to instantiate the new object...
		   my $new_object = bless \do{my $anon_scalar},	$class;

		   # Initialize	the object's "root" attribute...
		   $root_of{ident $new_object} = $root;

		   return $new_object;
	       }

	       # Retrieve files	from root directory...
	       sub get_files {
		   my ($self) =	@_;

		   # Load up the "files" attribute, if necessary...
		   if (!exists $files_of{ident $self}) {
		       $files_of{ident $self}
			   = File::System->list_files($root_of{ident $self});
		   }

		   # Flatten the "files" attribute's array to produce a	file list...
		   return @{ $files_of{ident $self} };
	       }
	   }

	   package File::Hierarchy::File;
	   {
	       # Objects of this class have the	following attributes...
	       my %name_of;  # the name	of the file

	       # Constructor takes name	of file...
	       sub new {
		   my ($class, $filename) = @_;

		   # Bless a scalar to instantiate the new object...
		   my $new_object = bless \do{my $anon_scalar},	$class;

		   # Initialize	the object's "name" attribute...
		   $name_of{ident $new_object} = $filename;

		   return $new_object;
	       }

	       # Retrieve name of file...
	       sub get_name {
		   my ($self) =	@_;

		   return $name_of{ident $self};
	       }
	   }

       Unlike a	hash-based class, each of these	inside-out class is specified
       inside a	surrounding code block:

	   package File::Hierarchy;
	   {
	       # [Class	specification here]
	   }

	   package File::Hierarchy::File;
	   {
	       # [Class	specification here]
	   }

       That block is vital, because it creates a limited scope,	to which any
       lexical variables that are declared as part of the class	will
       automatically be	restricted.

       The next	difference between the two versions of the classes is that
       each attribute of all the objects in the	class is now stored in a
       separate	single hash:

	   # Objects of	this class have	the following attributes...

	   my %root_of;	  # The	root directory of the file hierarchy
	   my %files_of;  # Array storing object for each file in root directory

       This is 90 degrees to the usual hash-based approach. In hash-based
       classes,	all the	attributes of one object are stored in a single	hash;
       in inside-out classes, one attribute from all objects is	stored in a
       single hash. Diagrammatically:

	   Hash-based:
			    Attribute 1	     Attribute 2

	    Object A	{ attr1	=> $valA1,  attr2 => $val2 }

	    Object B	{ attr1	=> $valB1,  attr2 => $val2 }

	    Object C	{ attr1	=> $valB1,  attr2 => $val2 }

	   Inside-out:
			     Object A		Object B	  Object C

	   Attribute 1	{ 19817	=> $valA1,  172616 => $valB1,  67142 =>	$valC1 }

	   Attribute 2	{ 19817	=> $valA2,  172616 => $valB2,  67142 =>	$valC3 }

	   Attribute 3	{ 19817	=> $valA3,  172616 => $valB3,  67142 =>	$valC3 }

       So the attributes belonging to each object are distributed across a set
       of predeclared hashes, rather than being	squashed together into one
       anonymous hash.

       This is a significant improvement. By telling Perl what attributes you
       expect to use, you enable the compiler to check--via use	strict--that
       you do indeed use only those attributes.

       That's because of the third difference in the two approaches. Each
       attribute of a hash-based object	is stored in an	entry in the object's
       hash: "$self->{name}". In other words, the name of a hash-based
       attribute is symbolic: specified	by the string value of a hash key. In
       contrast, each attribute	of an inside-out object	is stored in an	entry
       of the attribute's hash:	$name_of{ident $self}. So the name of an
       inside-out attribute isn't symbolic; it's a hard-coded variable name.

       With hash-based objects,	if an attribute	name is	accidentally
       misspelled in some method:

	   sub set_name	{
	       my ($self, $new_name) = @_;

	       $self->{naem} = $new_name;	      #	Oops!

	       return;
	   }

       then the	$self hash will	obligingly--and	silently!--create a new	entry
       in the hash, with the key 'naem', then assign the new name to it. But
       since every other method	in the class correctly refers to the attribute
       as "$self-"{name}>, assigning the new value to "$self-"{naem}>
       effectively makes that assigned value "vanish".

       With inside-out objects,	however, an object's "name" attribute is
       stored as an entry in the class's lexical %name_of hash.	If the
       attribute name is misspelled then you're	attempting to refer to an
       entirely	different hash:	%naem_of. Like so:

	   sub set_name	{
	       my ($self, $new_name) = @_;

	       $naem_of{ident $self} = $new_name;     #	Kaboom!

	       return;
	   }

       But, since there's no such hash declared	in the scope, use strict will
       complain	(with extreme prejudice):

	   Global symbol "%naem_of" requires explicit package name at Hierarchy.pm line	86

       Not only	is that	consistency check now automatic, it's also performed
       at compile time.

       The next	difference is even more	important and beneficial. Instead of
       blessing	an empty anonymous hash	as the new object:

	   my $new_object = bless {}, $class;

       the inside-out constructor blesses an empty anonymous scalar:

	   my $new_object = bless \do{my $anon_scalar},	$class;

       That odd-looking	"\do{my	$anon_scalar}" construct is needed because
       there's no built-in syntax in Perl for creating a reference to an
       anonymous scalar; you have to roll-your-own.

       The anonymous scalar is immediately passed to bless, which anoints it
       as an object of the appropriate class. The resulting object reference
       is then stored in $new_object.

       Once the	object exists, it's used to create a unique key	("ident
       $new_object") under which each attribute	that belongs to	the object
       will be stored (e.g. $root_of{ident $new_object}	or $name_of{ident
       $self}).	The "ident()" utility that produces this unique	key is
       provided	by the Class::Std module and is	identical in effect to the
       "refaddr()" function in the standard Scalar::Util module.

       To recap: every inside-out object is a blessed scalar, and
       has--intrinsic to it--a unique identifying integer. That	integer	can be
       obtained	from the object	reference itself, and then used	to access a
       unique entry for	the object in each of the class's attribute hashes.

       This means that every inside-out	object is nothing more than an
       unintialized scalar. When your constructor passes a new inside-out
       object back to the client code, all that	comes back is an empty scalar,
       which makes it impossible for that client code to gain direct access to
       the object's internal state.

       Of the several popular methods of reliably enforcing encapsulation in
       Perl, inside-out	objects	are also by far	the cheapest. The run-time
       performance of inside-out classes is effectively	identical to that of
       regular hash-based classes. In particular, in both schemes, every
       attribute access	requires only a	single hash look-up. The only
       appreciable difference in speed occurs when an inside-out object	is
       destroyed.

       Hash-based classes usually don't	even have destructors. When the
       object's	reference count	decrements to zero, the	hash is	automatically
       reclaimed, and any data structures stored inside	the hash are likewise
       cleaned up. This	works so well that many	OO Perl	programmers find they
       never need to write a "DESTROY()" method; Perl's	built-in garbage
       collection handles everything just fine.	In fact, the only time a
       destructor is needed is when objects have to manage resources outside
       that are	not actually located inside the	object,	resources that need to
       be separately deallocated.

       But the whole point of an inside-out object is that its attributes are
       stored in allocated hashes that are not actually	located	inside the
       object. That's precisely	how it achieves	secure encapsulation: by not
       sending the attributes out into the client code.

       Unfortunately, that means when an inside-out object is eventually
       garbage collected, the only storage that	is reclaimed is	the single
       blessed scalar implementing the object. The object's attributes are
       entirely	unaffected by the object's deallocation, because the
       attributes are not inside the object, nor are they referred to by it in
       any way.

       Instead,	the attributes are referred to by the various attribute	hashes
       in which	they're	stored.	And since those	hashes will continue to	exist
       until the end of	the program, the defunct object's orphaned attributes
       will likewise continue to exist,	safely nestled inside their respective
       hashes, but now untended	by any object. In other	words, when an inside-
       out object dies,	its associated attribute hashes	leak memory.

       The solution is simple. Every inside-out	class has to provide a
       destructor that "manually" cleans up the	attributes of the object being
       destructed:

	   package File::Hierarchy;
	   {
	       # Objects of this class have the	following attributes...
	       my %root_of;   #	The root directory of the file hierarchy
	       my %files_of;  #	Array storing object for each file in root directory

	       # Constructor takes path	of file	system root directory...
	       sub new {
		   # As	before
	       }

	       # Retrieve files	from root directory...
	       sub get_files {
		   # As	before
	       }

	       # Clean up attributes when object is destroyed...
	       sub DESTROY {
		   my ($self) =	@_;

		   delete $root_of{ident $self};
		   delete $files_of{ident $self};
	       }
	   }

       The obligation to provide a destructor like this	in every inside-out
       class can be mildly irritating, but it is still a very small price to
       pay for the considerable	benefits that the inside-out approach
       otherwise provides for free. And	the irritation can easily be
       eliminated by using the appropriate class construction tools. See
       below.

   Automating Inside-Out Classes
       Perhaps the most	annoying part about building classes in	Perl (no
       matter how the objects are implemented) is that the basic structure of
       every class is more or less identical. For example, the implementation
       of the "File::Hierarchy::File" class used in "File::Hierarchy" looks
       like this:

	   package File::Hierarchy::File;
	   {
	       # Objects of this class have the	following attributes...
	       my %name_of;  # the name	of the file

	       # Constructor takes name	of file...
	       sub new {
		   my ($class, $filename) = @_;

		   # Bless a scalar to instantiate the new object...
		   my $new_object = bless \do{my $anon_scalar},	$class;

		   # Initialize	the object's "name" attribute...
		   $name_of{ident $new_object} = $filename;

		   return $new_object;
	       }

	       # Retrieve name of file...
	       sub get_name {
		   my ($self) =	@_;

		   return $name_of{ident $self};
	       }

	       # Clean up attributes when object is destroyed...
	       sub DESTROY {
		   my ($self) =	@_;

		   delete $name_of{ident $self};
	       }
	   }

       Apart from the actual names of the attributes, and their	accessor
       methods,	that's exactly the same	structure, and even the	same code, as
       in the "File::Hierarchy"	class.

       Indeed, the standard infrastructure of every inside-out class looks
       exactly the same. So it makes sense not to have to rewrite that
       standard	infrastructure code in every separate class.

       That's precisely	what this module does: it implements the necessary
       infrastructure for inside-out objects. See below.

INTERFACE
   Exported subroutines
       "ident()"
	   Class::Std always exports a subroutine called "ident()". This
	   subroutine returns a	unique integer ID for any object passed	to it.

   Non-exported	subroutines
       "Class::Std::initialize()"
	   This	subroutine sets	up all the infrastructure to support your
	   Class::Std- based class. It is usually called automatically in a
	   "CHECK" block, or (if the "CHECK" block fails to run	-- under
	   "mod_perl" or "require Class::Std" or "eval "..."") during the
	   first constructor call made to a Class::Std-based object.

	   In rare circumstances, you may need to call this subroutine
	   directly yourself.  Specifically, if	you set	up cumulative,
	   restricted, private,	or automethodical class	methods	(see below),
	   and call any	of them	before you create any objects, then you	need
	   to call "Class::Std::initialize()" first.

   Methods created automatically
       The following subroutines are installed in any class that uses the
       Class::Std module.

       "new()"
	   Every class that loads the Class::Std module	automatically has a
	   "new()" constructor,	which returns an inside-out object (i.e. a
	   blessed scalar).

	       $obj = MyClass->new();

	   The constructor can be passed a single argument to initialize the
	   object. This	argument must be a hash	reference.

	       $obj = MyClass->new({ name=>'Foo', location=>'bar' });

	   See the subsequent descriptions of the "BUILD()" and	"START()"
	   methods and ":ATTR()" trait,	for an explanation of how the contents
	   of this optional hash can be	used to	initialize the object.

	   It is almost	always an error	to implement your own "new()" in any
	   class that uses Class::Std. You almost certainly want to write a
	   "BUILD()" or	"START()" method instead. See below.

       "DESTROY()"
	   Every class that loads the Class::Std module	automatically has a
	   "DESTROY()" destructor, which automatically cleans up any
	   attributes declared with the	":ATTR()" trait	(see below).

	   It is almost	always an error	to write your own "DESTROY()" in any
	   class that uses Class::Std. You almost certainly want to write your
	   own "DEMOLISH()" instead. See below.

       "AUTOLOAD()"
	   Every class that loads the Class::Std module	automatically has an
	   "AUTOLOAD()"	method,	which implements the "AUTOMETHOD()" mechanism
	   described below.

	   It is almost	always an error	to write your own "AUTOLOAD()" in any
	   class that uses Class::Std. You almost certainly want to write your
	   own "AUTOMETHOD()" instead.

       "_DUMP()"
	   This	method returns a string	that represents	the internal state
	   (i.e. the attribute values) of the object on	which it's called.
	   Only	those attributes which are marked with an ":ATTR" (see below)
	   are reported. Attribute names are reported only if they can be
	   ascertained from an ":init_arg", ":get", or ":set" option within
	   the ":ATTR()".

	   Note	that "_DUMP()" is not designed to support full
	   serialization/deserialization of objects. See the separate
	   Class::Std::Storable	module (on CPAN) for that.

   Methods that	can be supplied	by the developer
       The following subroutines can be	specified as standard methods of a
       Class::Std class.

       "BUILD()"
	   When	the "new()" constructor	of a Class::Std	class is called, it
	   automatically calls every method named "BUILD()" in all the classes
	   in the new object's hierarchy. That is, when	the constructor	is
	   called, it walks the	class's	inheritance tree (from base classes
	   downwards) and calls	every "BUILD()"	method it finds	along the way.

	   This	means that, to initialize any class, you merely	need to
	   provide a "BUILD()" method for that class. You don't	have to	worry
	   about ensuring that any ancestral "BUILD()" methods also get
	   called; the constructor will	take care of that.

	   Each	"BUILD()" method is called with	three arguments: the invocant
	   object, the identifier number of that object, and a reference to (a
	   customized version of) the hash of arguments	that was originally
	   passed to the constructor:

	       sub BUILD {
		   my ($self, $ident, $args_ref) = @_;
		   ...
	       }

	   The argument	hash is	a "customized version" because the module
	   automatically does some fancy footwork to ensure that the arguments
	   are the ones	appropriate to the class itself. That's	because
	   there's a potential for collisions when Class::Std classes are used
	   in a	hierarchy.

	   One of the great advantages of using	inside-out classes instead of
	   hash-based classes is that an inside-out base class and an inside-
	   out derived class can then each have	an attribute of	exactly	the
	   same	name, which are	stored in separate lexical hashes in separate
	   scopes. In a	hash-based object that's impossible, because the
	   single hash can't have two attributes with the same key.

	   But that very advantage also	presents something of a	problem	when
	   constructor arguments are themselves	passed by hash.	If two or more
	   classes in the name hierarchy do happen to have attributes of the
	   same	name, the constructor will need	two or more initializers with
	   the name key. Which a single	hash can't provide.

	   The solution	is to allow initializer	values to be partitioned into
	   distinct sets, each uniquely	named, and which are then passed to
	   the appropriate base	class. The easiest way to accomplish that is
	   to pass in a	hash of	hashes,	where each top level key is the	name
	   of one of the base classes, and the corresponding value is a	hash
	   of initializers specifically	for that base class.

	   For example:

	       package Client;
	       use Class::Std::Utils;
	       {
		   my %client_num_of :ATTR;  # Every client has	a basic	ID number
		   my %name_of	     :ATTR;

		   sub BUILD {
		       my ($self, $ident, $arg_ref) = @_;

		       $client_num_of{$ident} =	$arg_ref->{'Client'}{client_num};
		       $name_of{$ident}	      =	$arg_ref->{'Client'}{client_name};
		   }
	       }

	       package Client::Corporate;
	       use base	qw( Client );
	       use Class::Std::Utils;
	       {
		   my %client_num_of;	  # Corporate clients have an additional ID number
		   my %corporation_of;
		   my %position_of;

		   sub BUILD {
		       my ($self, $ident, $arg_ref) = @_;

		       $client_num_of{$ident}
			   = $arg_ref->{'Client::Corporate'}{client_num};
		       $corporation_of{$ident}
			   = $arg_ref->{'Client::Corporate'}{corp_name};
		       $position_of{$ident}
			   = $arg_ref->{'Client::Corporate'}{position};
		   }
	       }

	       # and later...

	       my $new_client
		   = Client::Corporate->new( {
		       'Client'	=> {
			   client_num  => '124C1',
			   client_name => 'Humperdinck',
		       },
		       'Client::Corporate' => {
			   client_num  => 'F_1692',
			   corp_name   => 'Florin',
			   position    => 'CEO',
		       },
		   });

	   Now each class's "BUILD()" method picks out only the	initializer
	   sub-hash whose key is that class's own name.	Since every class name
	   is different, the top-level keys of this multi-level	initializer
	   hash	are guaranteed to be unique. And since no single class can
	   have	two identically	named attributes, the keys of each second-
	   level hash will be unique as	well. If two classes in	the hierarchy
	   both	need an	initializer of the same	name (e.g. 'client_num'),
	   those two hash entries will now be in separate sub-hashes, so they
	   will	never clash.

	   Class::Std provides an even more sophisticated variation on this
	   functionality, which	is generally much more convenient for the
	   users of classes. Classes that use Class::Std infrastructure	allow
	   both	general	and class-specific initializers	in the initialization
	   hash. Clients only need to specify classes for those	initializers
	   whose names actually	are ambiguous. Any other arguments can just be
	   passed directly in the top-level hash:

	       my $new_client
		   = Client::Corporate->new( {
		       client_name => 'Humperdinck',
		       corp_name   => 'Florin',
		       position	   => 'CEO',

		       'Client'		   => {	client_num  => '124C1'	},
		       'Client::Corporate' => {	client_num  => 'F_1692'	},
		   });

	   Class::Std also makes it easy for each class's "BUILD()" to access
	   these class-specific	initializer values. Before each	"BUILD()" is
	   invoked, the	nested hash whose key is the same as the class name is
	   flattened back into the initializer hash itself. That is,
	   "Client::BUILD()" is	passed the hash:

	       {
		   client_name => 'Humperdinck',
		   corp_name   => 'Florin',
		   position    => 'CEO',
		   client_num  => '124C1',   # Flattened from 'Client' nested subhash

		   'Client'	       => { client_num	=> '124C1'  },
		   'Client::Corporate' => { client_num	=> 'F_1692' },
	       }

	   whereas "Client::Corporate::BUILD()"	is passed the hash:

	       {
		   client_name => 'Humperdinck',
		   corp_name   => 'Florin',
		   position    => 'CEO',
		   client_num  => 'F_1692',   #	Flattened from 'Client::Corporate' subhash

		   'Client'	       => { client_num	=> '124C1'  },
		   'Client::Corporate' => { client_num	=> 'F_1692' },
	       }

	   This	means that the "BUILD()" method	for each class can just	assume
	   that	the correct class-specific initializer values will available
	   at the top level of the hash. For example:

		   sub Client::BUILD {
		       my ($self, $ident, $arg_ref) = @_;

		       $client_num_of{$ident} =	$arg_ref->{client_num};	   # '124C1'
		       $name_of{$ident}	      =	$arg_ref->{client_name};
		   }

		   sub Client::Corporate::BUILD	{
		       my ($self, $ident, $arg_ref) = @_;

		       $client_num_of{$ident}  = $arg_ref->{client_num};   # 'F_1692'
		       $corporation_of{$ident} = $arg_ref->{corp_name};
		       $position_of{$ident}    = $arg_ref->{position};
		   }

	   Both	classes	use the	"$arg_ref->{client_num}" initializer value,
	   but Class::Std automatically	arranges for that value	to be the
	   right one for each class.

	   Also	see the	":ATTR()" marker (described below) for a simpler way
	   of initializing attributes.

       "START()"
	   Once	all the	"BUILD()" methods of a class have been called and any
	   initialization values or defaults have been subsequently applied to
	   uninitialized attributes, Class::Std	arranges for any "START()"
	   methods in the class's hierarchy to be called befre the constructor
	   finishes.  That is, after the build and default initialization
	   processes are complete, the constructor walks down the class's
	   inheritance tree a second time and calls every "START()" method it
	   finds along the way.

	   As with "BUILD()", each "START()" method is called with three
	   arguments: the invocant object, the identifier number of that
	   object, and a reference to (a customized version of)	the hash of
	   arguments that was originally passed	to the constructor.

	   The main difference between a "BUILD()" method and a	"START()"
	   method is that a "BUILD()" method runs before any attribute of the
	   class is auto-initialized or	default-initialized, whereas a
	   "START()" method runs after all the attributes of the class
	   (including attributes in derived classes) have been initialized in
	   some	way. So	if you want to pre-empt	the initialization process,
	   write a "BUILD()". But if you want to do something with the newly
	   created and fully initialized object, write a "START()" instead. Of
	   course, any class can define	both a "BUILD()" and a "START()"
	   method, if that happens to be appropriate.

       "DEMOLISH()"
	   The "DESTROY()" method that is automatically	provided by Class::Std
	   ensures that	all the	marked attributes (see the ":ATTR()" marker
	   below) of an	object,	from all the classes in	its inheritance
	   hierarchy, are automatically	cleaned	up.

	   But,	if a class requires other destructor behaviours	(e.g. closing
	   filehandles,	decrementing allocation	counts,	etc.) then you may
	   need	to specify those explicitly.

	   Whenever an object of a Class::Std class is destroyed, the
	   "DESTROY()" method supplied by Class::Std automatically calls every
	   method named	"DEMOLISH()" in	all the	classes	in the new object's
	   hierarchy. That is, when the	destructor is called, it walks the
	   class's inheritance tree (from derived classes upwards) and calls
	   every "DEMOLISH()" method it	finds along the	way.

	   This	means that, to clean up	any class, you merely need to provide
	   a "DEMOLISH()" method for that class. You don't have	to worry about
	   ensuring that any ancestral "DEMOLISH()" methods also get called;
	   the destructor will take care of that.

	   Each	"DEMOLISH()" method is called with two arguments: the invocant
	   object, and the identifier number of	that object. For example:

	       sub DEMOLISH {
		   my ($self, $ident) =	@_;

		   $filehandle_of{$ident}->flush();
		   $filehandle_of{$ident}->close();
	       }

	   Note	that the attributes of the object are cleaned up after the
	   "DEMOLISH()"	method is complete, so they may	still be used within
	   that	method.

       "AUTOMETHOD()"
	   There is a significant problem with Perl's built-in "AUTOLOAD"
	   mechanism: there's no way for a particular "AUTOLOAD()" to say
	   "no".

	   If two or more classes in a class hierarchy have separate
	   "AUTOLOAD()"	methods, then the one belonging	to the left-most-
	   depth-first class in	the inheritance	tree will always be invoked in
	   preference to any others.  If it can't handle a particular call,
	   the call will probably fail catastrophically. This means that
	   derived classes can't always	be used	in place of base classes (a
	   feature known as "Liskov substitutability") because their inherited
	   autoloading behaviour may be	pre-empted by some other unrelated
	   base	class on their left in the hierarchy.

	   Class::Std provides a mechanism that	solves this problem: the
	   "AUTOMETHOD"	method.	An AUTOMETHOD()	is expected to return either a
	   handler subroutine that implements the requested method
	   functionality, or else an "undef" to	indicate that it doesn't know
	   how to handle the request. Class::Std then coordinates every
	   "AUTOMETHOD()" in an	object's hierarchy, trying each	one in turn
	   until one of	them produces a	suitable handler.

	   The advantage of this approach is that the first "AUTOMETHOD()"
	   that's invoked doesn't have to disenfranchise every other
	   "AUTOMETHOD()" in the hierarchy. If the first one can't handle a
	   particular method call, it simply declines it and Class::Std	tries
	   the next candidate instead.

	   Using "AUTOMETHOD()"	instead	of "AUTOLOAD()"	makes a	class cleaner,
	   more	robust,	and less disruptive in class hierarchies.  For
	   example:

	       package Phonebook;
	       use Class::Std;
	       {
		   my %entries_of : ATTR;

		   # Any method	call is	someone's name:
		   # so	store their phone number or get	it...
		   sub AUTOMETHOD {
		       my ($self, $ident, $number) = @_;

		       my $subname = $_;   # Requested subroutine name is passed via $_

		       # Return	failure	if not a get_<name> or set_<name>
		       # (Next AUTOMETHOD() in hierarchy will then be tried instead)...
		       my ($mode, $name) = $subname =~ m/\A ([gs]et)_(.*) \z/xms
			   or return;

		       # If get_<name>,	return a handler that just returns the old number...
		       return sub { return $entries_of{$ident}->{$name}; }
			   if $mode eq 'get';

		       # Otherwise, set_<name>,	so return a handler that
		       # updates the entry and then returns the	old number...
		       return sub {
			   $entries_of{$ident}->{$name}	= $number;
			   return;
		       };
		   }
	       }

	       # and later...

	       my $lbb = Phonebook->new();

	       $lbb->set_Jenny(867_5309);
	       $lbb->set_Glenn(736_5000);

	       print $lbb->get_Jenny(),	"\n";
	       print $lbb->get_Glenn(),	"\n";

	   Note	that, unlike "AUTOLOAD()", an "AUTOMETHOD()" is	called with
	   both	the invocant and the invocant's	unique "ident" number,
	   followed by the actual arguments that were passed to	the method.

	   Note	too that the name of the method	being called is	passed as $_
	   instead of $AUTOLOAD, and does not have the class name prepended to
	   it, so you don't have to strip that name off	the front like almost
	   everyone almost always does in their	"AUTOLOAD()". If your
	   "AUTOMETHOD()" also needs to	access the $_ from the caller's	scope,
	   that's still	available as $CALLER::_.

   Variable traits that	can be ascribed
       The following markers can be added to the definition of any hash	used
       as an attribute storage within a	Class::Std class

       ":ATTR()"
	   This	marker can be used to indicate that a lexical hash is being
	   used	to store one particular	attribute of all the objects of	the
	   class. That is:

	       package File::Hierarchy;
	       {
		   my %root_of	:ATTR;
		   my %files_of	:ATTR;

		   # etc.
	       }

	       package File::Hierarchy::File;
	       {
		   my %name_of;	 :ATTR;

		   # etc.
	       }

	   Adding the ":ATTR" marker to	an attribute hash ensures that the
	   corresponding attribute belonging to	each object of the class is
	   automatically cleaned up when the object is destroyed.

	   The ":ATTR" marker can also be given	a number of options which
	   automate other attribute-related behaviours.	Each of	these options
	   consists of a key/value pair, which may be specified	in either Perl
	   5 "fat comma" syntax	( "keyA	=>A 'value'" ) or in one of the	Perl 6
	   option syntaxes ( ":key<value>" or ":key('value')" or
	   ":keyA<<valueA>>").

	   Note	that, due to a limitation in Perl itself, the complete ":ATTR"
	   marker, including its options must appear on	a single line.
	   interpolate variables into the option values

	   ":ATTR( :init_arg<initializer_key> )"
	       This option tells Class::Std which key in the constructor's
	       initializer hash	holds the value	with which the marked
	       attribute should	be initialized.	That is, instead of writing:

		   my %rank_of :ATTR;

		   sub BUILD {
		       my ($self, $ident, $arg_ref) = @_;

		       $rank_of{$ident}	= $arg_ref->{rank};
		   }

	       you can achieve the same	initialization,	by having Class::Std
	       automatically pull that entry out of the	hash and store it in
	       the right attribute:

		   my %rank_of :ATTR( :init_arg<rank> );

		   # No	BUILD()	method required

	   ":ATTR( :default<compile_time_default_value>	)"
	       If a marked attribute is	not initialized	(either	directly
	       within a	"BUILD()", or automatically via	an ":init_arg"
	       option),	the constructor	supplied by Class::Std checks to see
	       if a default value was specified	for that attribute. If so,
	       that value is assigned to the attribute.

	       So you could replace:

		   my %seen_of :ATTR;

		   sub BUILD {
		       my ($self, $ident, $arg_ref) = @_;

		       $seen_of{$ident}	= 0;  #	Not seen yet
		   }

	       with:

		   my %seen_of :ATTR( :default(0) );

		   # No	BUILD()	required

	       Note that only literal strings and numbers can be used as
	       default values. A common	mistake	is to write:

		   my %seen_of :ATTR( :default($some_variable) );

	       But variables like this aren't interpolated into	":ATTR"
	       markers (this is	a limitation of	Perl, not Class::Std).

	       If your attribute needs something more complex, you will	have
	       to default initialize it	in a "START()" method:

		   my %seen_of :ATTR;

		   sub START {
		       my ($self, $id, $args_ref) = @_;

		       if (!defined $seen_of{$id}) {
			   $seen_of{$id} = $some_variable;
		       }
		   }

	   ":ATTR( :get<name> )"
	       If the ":get" option is specified, a read accessor is created
	       for the corresponding attribute.	The name of the	accessor is
	       "get_" followed by whatever name	is specified as	the value of
	       the ":get" option. For example, instead of:

		   my %current_count_of	:ATTR;

		   sub get_count {
		       my ($self) = @_;

		       return $current_count_of{ident($self)};
		   }

	       you can just write:

		   my %count_of	:ATTR( :get<count> );

	       Note that there is no way to prevent Class::Std adding the
	       initial "get_" to each accessor name it creates.	That's what
	       "standard" means. See Chapter 15	of Perl	Best Practices
	       (O'Reilly, 2005)	for a full discussion on why accessors should
	       be named	this way.

	   ":ATTR( :set<name> )"
	       If the ":set" option is specified, a write accessor is created
	       for the corresponding attribute.	The name of the	accessor is
	       "set_" followed by whatever name	is specified as	the value of
	       the ":set" option. For example, instead of:

		   my %current_count_of	:ATTR;

		   sub set_count {
		       my ($self, $new_value) =	@_;

		       croak "Missing new value	in call	to 'set_count' method"
			   unless @_ ==	2;

		       $current_count_of{ident($self)} = $new_value;
		   }

	       you can just write:

		   my %count_of	:ATTR( :set<count> );

	       Note that there is no way to prevent Class::Std adding the
	       initial "set_" to each accessor name it creates.	Nor is there
	       any way to create a combined "getter/setter" accessor. See
	       Chapter 15 of Perl Best Practices (O'Reilly, 2005) for a	full
	       discussion on why accessors should be named and implemented
	       this way.

	   ":ATTR( :name<name> )"
	       Specifying the ":name" option is	merely a convenient shorthand
	       for specifying all three	of ":get", ":set", and ":init_arg".

	   You can, of course, specify two or more arguments in	a single
	   ":ATTR()" specification:

	       my %rank_of : ATTR( :init_arg<starting_rank>  :get<rank>	 :set<rank> );

       ":ATTRS()"
	   This	is just	another	name for the ":ATTR" marker (see above). The
	   plural form is convenient when you want to specify a	series of
	   attribute hashes in the same	statement:

	       my (
		   %name_of,
		   %rank_of,
		   %snum_of,
		   %age_of,
		   %unit_of,
		   %assignment_of,
		   %medals_of,
	       ) : ATTRS;

   Method traits that can be ascribed
       The following markers can be added to the definition of any subroutine
       used as a method	within a Class::Std class

       ":RESTRICTED()"
       ":PRIVATE()"
	   Occasionally, it is useful to be able to create subroutines that
	   can only be accessed	within a class's own hierarchy (that is, by
	   derived classes). And sometimes it's	even more useful to be able to
	   create methods that can only	be called within a class itself.

	   Typically these types of methods are	utility	methods: subroutines
	   that	provide	some internal service for a class, or a	class
	   hierarchy.  Class::Std supports the creation	of these kinds of
	   methods by providing	two special markers: ":RESTRICTED()" and
	   ":PRIVATE()".

	   Methods marked ":RESTRICTED()" are modified at the end of the
	   compilation phase so	that they throw	an exception when called from
	   outside a class's hierarchy.	Methods	marked ":PRIVATE()" are
	   modified so that they throw an exception when called	from outside
	   the class in	which they're declared.

	   For example:

	       package DogTag;
	       use Class::Std;
	       {
		   my %ID_of   : ATTR;
		   my %rank_of : ATTR;

		   my $ID_num =	0;

		   sub _allocate_next_ID : RESTRICTED {
		       my ($self) = @_;
		       $ID_of{ident $self} = $ID_num++;
		       return;
		   }

		   sub _check_rank : PRIVATE {
		       my ($rank) = @_;
		       return $rank if $VALID_RANK{$rank};
		       croak "Unknown rank ($rank) specified";
		   }

		   sub BUILD {
		       my ($self, $ident, $arg_ref) = @_;

		       $self->_allocate_next_ID();
		       $rank_of{$ident}	= _check_rank($arg_ref->{rank});
		   }
	       }

	   Of course, this code	would run exactly the same without the
	   ":RESTRICTED()" and ":PRIVATE()" markers, but they ensure that any
	   attempt to call the two subroutines inappropriately:

	       package main;

	       my $dogtag = DogTag->new({ rank => 'PFC'	});

	       $dogtag->_allocate_next_ID();

	   is suitably punished:

	       Can't call restricted method DogTag::_allocate_next_ID()	from class main

       ":CUMULATIVE()"
	   One of the most important advantages	of using the "BUILD()" and
	   "DEMOLISH()"	mechanisms supplied by Class::Std is that those
	   methods don't require nested	calls to their ancestral methods, via
	   the "SUPER" pseudo-class. The constructor and destructor provided
	   by Class::Std take care of the necessary redispatching
	   automatically. Each "BUILD()" method	can focus solely on its	own
	   responsibilities; it	doesn't	have to	also help orchestrate the
	   cumulative constructor effects across the class hierarchy by
	   remembering to call "$self->SUPER::BUILD()".

	   Moreover, calls via "SUPER" can only	ever call the method of
	   exactly one ancestral class,	which is not sufficient	under multiple
	   inheritance.

	   Class::Std provides a different way of creating methods whose
	   effects accumulate through a	class hierarchy, in the	same way as
	   those of "BUILD()" and "DEMOLISH()" do. Specifically, the module
	   allows you to define	your own "cumulative methods".

	   An ordinary non-cumulative method hides any method of the same name
	   inherited from any base class, so when a non-cumulative method is
	   called, only	the most-derived version of it is ever invoked.	In
	   contrast, a cumulative method doesn't hide ancestral	methods	of the
	   same	name; it assimilates them. When	a cumulative method is called,
	   the most-derived version of it is invoked, then any parental
	   versions, then any grandparental versions, etc. etc,	until every
	   cumulative method of	the same name throughout the entire hierarchy
	   has been called.

	   For example,	you could define a cumulative "describe()" method to
	   the various classes in a simple class hierarchy like	so:

	       package Wax::Floor;
	       use Class::Std;
	       {
		   my %name_of	  :ATTR( init_arg => 'name'   );
		   my %patent_of  :ATTR( init_arg => 'patent' );

		   sub describe	:CUMULATIVE {
		       my ($self) = @_;

		       print "The floor	wax $name_of{ident $self} ",
			     "(patent: $patent_of{ident	$self})\n";

		       return;
		   }
	       }

	       package Topping::Dessert;
	       use Class::Std;
	       {
		   my %name_of	   :ATTR( init_arg => 'name'	);
		   my %flavour_of  :ATTR( init_arg => 'flavour'	);

		   sub describe	:CUMULATIVE {
		       my ($self) = @_;

		       print "The dessert topping $name_of{ident $self}	",
			     "with that	great $flavour_of{ident	$self} taste!\n";

		       return;
		   }
	       }

	       package Shimmer;
	       use base	qw( Wax::Floor	Topping::Dessert );
	       use Class::Std;
	       {
		   my %name_of	  :ATTR( init_arg => 'name'   );
		   my %patent_of  :ATTR( init_arg => 'patent' );

		   sub describe	:CUMULATIVE {
		       my ($self) = @_;

		       print "New $name_of{ident $self}	",
			     "(patent: $patent_of{ident	$self})\n",
			     "Combining...\n";

		       return;
		   }
	       }

	   Because the various "describe()" methods are	marked as being
	   cumulative, a subsequent call to:

	       my $product
		   = Shimmer->new({
			 name	 => 'Shimmer',
			 patent	 => 1562516251,
			 flavour => 'Vanilla',
		     });

	       $product->describe();

	   will	work its way up	through	the classes of Shimmer's inheritance
	   tree	(in the	same order as a	destructor call	would),	calling	each
	   "describe()"	method it finds	along the way. So the single call to
	   "describe()"	would invoke the corresponding method in each class,
	   producing:

	       New Shimmer (patent: 1562516251)
	       Combining...
	       The floor wax Shimmer (patent: 1562516251)
	       The dessert topping Shimmer with	that great Vanilla taste!

	   Note	that the accumulation of "describe()" methods is hierarchical,
	   and dynamic in nature. That is, each	class only sees	those
	   cumulative methods that are defined in its own package or in	one of
	   its ancestors.  So calling the same "describe()" on a base class
	   object:

	       my $wax
		   = Wax::Floor->new({ name=>'Shimmer ', patent=>1562516251 });

	       $wax->describe();

	   only	invokes	the corresponding cumulative methods from that point
	   on up the hierarchy,	and hence only prints:

	       The floor wax Shimmer (patent: 1562516251)

	   Cumulative methods also accumulate their return values. In a	list
	   context, they return	a (flattened) list that	accumulates the	lists
	   returned by each individual method invoked.

	   In a	scalar context,	a set of cumulative methods returns an object
	   that, in a string context, concatenates individual scalar returns
	   to produce a	single string. When used as an array reference that
	   same	scalar-context-return object acts like an array	of the list
	   context values. When	used as	a hash reference, the object acts like
	   a hash whose	keys are the classnames	from the object's hierarchy,
	   and whose corresponding values are the return values	of the
	   cumulative method from that class.

	   For example,	if the classes each have a cumulative method that
	   returns their list of sales features:

	       package Wax::Floor;
	       use Class::Std;
	       {
		   sub feature_list :CUMULATIVE	{
		       return ('Long-lasting', 'Non-toxic', 'Polymer-based');
		   }
	       }

	       package Topping::Dessert;
	       use Class::Std;
	       {
		   sub feature_list :CUMULATIVE	{
		       return ('Low-carb', 'Non-dairy',	'Sugar-free');
		   }
	       }

	       package Shimmer;
	       use Class::Std;
	       use base	qw( Wax::Floor	Topping::Dessert );
	       {
		   sub feature_list :CUMULATIVE	{
		       return ('Multi-purpose',	'Time-saving', 'Easy-to-use');
		   }
	       }

	   then	calling	feature_list() in a list context:

	       my @features = Shimmer->feature_list();
	       print "Shimmer is the @features alternative!\n";

	   would produce a concatenated	list of	features, which	could then be
	   interpolated	into a suitable	sales-pitch:

	       Shimmer is the Multi-purpose Time-saving	Easy-to-use
	       Long-lasting Non-toxic Polymer-based Low-carb Non-dairy
	       Sugar-free alternative!

	   It's	also possible to specify a set of cumulative methods that
	   start at the	base class(es) of the hierarchy	and work downwards,
	   the way BUILD() does. To get	that effect, you simply	mark each
	   method with :CUMULATIVE(BASE	FIRST),	instead	of just	:CUMULATIVE.
	   For example:

	       package Wax::Floor;
	       use Class::Std;
	       {
		   sub active_ingredients :CUMULATIVE(BASE FIRST) {
		       return "\tparadichlorobenzene, cyanoacrylate, peanuts\n";
		   }
	       }

	       package Topping::Dessert;
	       use Class::Std;
	       {
		   sub active_ingredients :CUMULATIVE(BASE FIRST) {
		       return "\tsodium	hypochlorite, isobutyl ketone, ethylene	glycol\n";
		   }
	       }

	       package Shimmer;
	       use Class::Std;
	       use base	qw( Wax::Floor	Topping::Dessert );

	       {
		   sub active_ingredients :CUMULATIVE(BASE FIRST) {
		       return "\taromatic hydrocarbons,	xylene,	methyl mercaptan\n";
		   }
	       }

	   So a	scalar-context call to active_ingredients():

	       my $ingredients = Shimmer->active_ingredients();
	       print "May contain trace	amounts	of:\n$ingredients";

	   would start in the base classes and work downwards, concatenating
	   base- class ingredients before those	of the derived class, to
	   produce:

	       May contain trace amounts of:
		   paradichlorobenzene,	cyanoacrylate, peanuts
		   sodium hypochlorite,	isobutyl ketone, ethylene glycol
		   aromatic hydrocarbons, xylene, methyl mercaptan

	   Or, you could treat the return value	as a hash:

	       print Data::Dumper::Dumper \%{$ingredients};

	   and see which ingredients came from where:

	       $VAR1 = {
		  'Shimmer'
		       => 'aromatic hydrocarbons, xylene, methyl mercaptan',

		  'Topping::Dessert'
		       => 'sodium hypochlorite,	isobutyl ketone, ethylene glycol',

		   'Wax::Floor'
		       => 'Wax:	paradichlorobenzene,  hydrogen peroxide, cyanoacrylate',
	       };

	   Note	that you can't specify both ":CUMULATIVE" and
	   ":CUMULATIVE(BASE FIRST)" on	methods	of the same name in the	same
	   hierarchy. The resulting set	of methods would have no well-defined
	   invocation order, so	Class::Std throws a compile-time exception
	   instead.

       ":STRINGIFY"
	   If you define a method and add the ":STRINGIFY" marker then that
	   method is used whenever an object of	the corresponding class	needs
	   to be coerced to a string. In other words, instead of:

	       # Convert object	to a string...
	       sub as_str {
		   ...
	       }

	       # Convert object	to a string automatically in string contexts...
	       use overload (
		   q{""}    => 'as_str',
		   fallback => 1,
	       );

	   you can just	write:

	       # Convert object	to a string (automatically in string contexts)...
	       sub as_str : STRINGIFY {
		   ...
	       }

       ":NUMERIFY"
	   If you define a method and add the ":NUMERIFY" marker then that
	   method is used whenever an object of	the corresponding class	needs
	   to be coerced to a number. In other words, instead of:

	       # Convert object	to a number...
	       sub as_num {
		   ...
	       }

	       # Convert object	to a string automatically in string contexts...
	       use overload (
		   q{0+}    => 'as_num',
		   fallback => 1,
	       );

	   you can just	write:

	       # Convert object	to a number (automatically in numeric contexts)...
	       sub as_num : NUMERIFY {
		   ...
	       }

       ":BOOLIFY"
	   If you define a method and add the ":BOOLIFY" marker	then that
	   method is used whenever an object of	the corresponding class	needs
	   to be coerced to a boolean value. In	other words, instead of:

	       # Convert object	to a boolean...
	       sub as_bool {
		   ...
	       }

	       # Convert object	to a boolean automatically in boolean contexts...
	       use overload (
		   q{bool}    => 'as_bool',
		   fallback => 1,
	       );

	   you can just	write:

	       # Convert object	to a boolean (automatically in boolean contexts)...
	       sub as_bool : BOOLIFY {
		   ...
	       }

       ":SCALARIFY"
       ":ARRAYIFY"
       ":HASHIFY"
       ":GLOBIFY"
       ":CODIFY"
	   If a	method is defined with one of these markers, then it is
	   automatically called	whenever an object of that class is treated as
	   a reference of the corresponding type.

	   For example,	instead	of:

	       sub as_hash {
		   my ($self) =	@_;

		   return {
		       age	=> $age_of{ident $self},
		       shoesize	=> $shoe_of{ident $self},
		   };
	       }

	       use overload (
		   '%{}'    => 'as_hash',
		   fallback => 1,
	       );

	   you can just	write:

	       sub as_hash : HASHIFY {
		   my ($self) =	@_;

		   return {
		       age	=> $age_of{ident $self},
		       shoesize	=> $shoe_of{ident $self},
		   };
	       }

	   Likewise for	methods	that allow an object to	be treated as a	scalar
	   reference (":SCALARIFY"), a array reference (":ARRAYIFY"), a
	   subroutine reference	(":CODIFY"), or	a typeglob reference
	   (":GLOBIFY").

DIAGNOSTICS
       Can't find class	%s
	   You tried to	call the Class::Std::new() constructor on a class that
	   isn't built using Class::Std. Did you forget	to write "use
	   Class::Std" after the package declaration?

       Argument	to %s->new() must be hash reference
	   The constructors created by Class::Std require all initializer
	   values to be	passed in a hash, but you passed something that	wasn't
	   a hash.  Put	your constructor arguments in a	hash.

       Missing initializer label for %s: %s
	   You specified that one or more attributes had initializer values
	   (using the "init" argument inside the attribute's "ATTR" marker),
	   but then failed to pass in the corresponding	initialization value.
	   Often this happens because the initialization value was passed, but
	   the key specifying the attribute name was misspelled.

       Can't make anonymous subroutine cumulative
	   You attempted to use	the ":CUMULATIVE" marker on an anonymous
	   subroutine.	But that marker	can only be applied to the named
	   methods of a	class. Convert the anonymous subroutine	to a named
	   subroutine, or find some other way to make it interoperate with
	   other methods.

       Conflicting definitions for cumulative method: %s
	   You defined a ":CUMULATIVE" and a ":CUMULATIVE(BASE FIRST)" method
	   of the same name in two classes within the same hierarchy. Since
	   methods can only be called going strictly up	through	the hierarchy
	   or going strictly down through the hierarchy, specifying both
	   directions is obviously a mistake.  Either rename one of the
	   methods, or decide whether they should accumulate upwards or
	   downwards.

       Missing new value in call to 'set_%s' method
	   You called an attribute setter method without providing a new value
	   for the attribute. Often this happens because you passed an array
	   that	happened to be empty. Make sure	you pass an actual value.

       Can't locate %s method "%s" via package %s
	   You attempted to call a method on an	object but no such method is
	   defined anywhere in the object's class hierarchy. Did you misspell
	   the method name, or perhaps misunderstand which class the object
	   belongs to?

       %s method %s declared but not defined
	   A method was	declared with a	":RESTRICTED" or ":PRIVATE", like so:

	       sub foo :RESTRICTED;
	       sub bar :PRIVATE;

	   But the actual subroutine was not defined by	the end	of the
	   compilation phase, when the module needed it	so it could be
	   rewritten to	restrict or privatize it.

       Can't call restricted method %s from class %s
	   The specified method	was declared with a ":RESTRICTED" marker but
	   subsequently	called from outside its	class hierarchy. Did you call
	   the wrong method, or	the right method from the wrong	place?

       Can't call private method %s from class %s
	   The specified method	was declared with a ":PRIVATE" marker but
	   subsequently	called from outside its	own class. Did you call	the
	   wrong method, or the	right method from the wrong place?

       Internal	error: %s
	   Your	code is	okay, but it uncovered a bug in	the Class::Std module.
	   "BUGS AND LIMITATIONS" explains how to report the problem.

CONFIGURATION AND ENVIRONMENT
       Class::Std requires no configuration files or environment variables.

DEPENDENCIES
       Class::Std depends on the following modules:

       o   version

       o   Scalar::Util

       o   Data::Dumper

INCOMPATIBILITIES
       Incompatible with the Attribute::Handlers module, since both define
       meta-attributes named :ATTR.

BUGS AND LIMITATIONS
       o   Does	not handle threading (including	"fork()" under Windows).

       o   ":ATTR" declarations	must all be on the same	line (due to a
	   limitation in Perl itself).

       o   ":ATTR" declarations	cannot include variables, since	these are not
	   interpolated	into the declaration (a	limitation in Perl itself).

       Please report any bugs or feature requests to
       "bug-class-std@rt.cpan.org", or through the web interface at
       <http://rt.cpan.org>.

ALTERNATIVES
       Inside-out objects are gaining in popularity and	there are now many
       other modules that implement frameworks for building inside-out
       classes.	These include:

       Object::InsideOut
	   Array-based objects,	with support for threading. Many excellent
	   features (especially	thread-safety),	but slightly less secure than
	   Class::Std, due to non-encapsulation	of attribute data addressing.

       Class::InsideOut
	   A minimalist	approach to building inside-out	classes.

       Lexical::Attributes
	   Uses	source filters to provide a near-Perl 6	approach to declaring
	   inside-out classes.

       Class::Std::Storable
	   Adds	serialization/deserialization to Class::Std.

AUTHOR
       Damian Conway  "<DCONWAY@cpan.org>"

LICENCE	AND COPYRIGHT
       Copyright (c) 2005, Damian Conway "<DCONWAY@cpan.org>". All rights
       reserved.

       Portions	of the documentation from "Perl	Best Practices"	copyright (c)
       2005 by O'Reilly	Media, Inc. and	reprinted with permission.

       This module is free software; you can redistribute it and/or modify it
       under the same terms as Perl itself.

DISCLAIMER OF WARRANTY
       BECAUSE THIS SOFTWARE IS	LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
       FOR THE SOFTWARE, TO THE	EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT
       WHEN OTHERWISE STATED IN	WRITING	THE COPYRIGHT HOLDERS AND/OR OTHER
       PARTIES PROVIDE THE SOFTWARE "AS	IS" WITHOUT WARRANTY OF	ANY KIND,
       EITHER EXPRESSED	OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
       ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF	THE SOFTWARE IS	WITH
       YOU. SHOULD THE SOFTWARE	PROVE DEFECTIVE, YOU ASSUME THE	COST OF	ALL
       NECESSARY SERVICING, REPAIR, OR CORRECTION.

       IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR	AGREED TO IN WRITING
       WILL ANY	COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
       REDISTRIBUTE THE	SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE
       TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR
       CONSEQUENTIAL DAMAGES ARISING OUT OF THE	USE OR INABILITY TO USE	THE
       SOFTWARE	(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
       RENDERED	INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
       FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
       SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
       DAMAGES.

perl v5.32.1			  2015-05-24			 Class::Std(3)

NAME | VERSION | SYNOPSIS | DESCRIPTION | INTERFACE | DIAGNOSTICS | CONFIGURATION AND ENVIRONMENT | DEPENDENCIES | INCOMPATIBILITIES | BUGS AND LIMITATIONS | ALTERNATIVES | AUTHOR | LICENCE AND COPYRIGHT | DISCLAIMER OF WARRANTY

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

home | help