This is Info file pm.info, produced by Makeinfo version 1.68 from the
input file bigpm.texi.


File: pm.info,  Node: Class/Accessor/Fast,  Next: Class/Autouse,  Prev: Class/Accessor,  Up: Module List

Faster, but less expandable, accessors
**************************************

NAME
====

   Class::Accessor::Fast - Faster, but less expandable, accessors

SYNOPSIS
========

     package Foo;
     use base qw(Class::Accessor::Fast);

     # The rest as Class::Accessor except no set() or get().

DESCRIPTION
===========

   This is a somewhat faster, but less expandable, version of
Class::Accessor.  Class::Accessor's generated accessors require two method
calls to accompish their task (one for the accessor, another for get() or
set()).  Class::Accessor::Fast eliminates calling set()/get() and does the
access itself, resulting in a somewhat faster accessor.

   The downside is that you can't easily alter the behavior of your
accessors, nor can your subclasses.  Of course, should you need this
later, you can always swap out Class::Accessor::Fast for Class::Accessor.

EFFICIENCY
==========

   `EFFICIENCY', *Note Class/Accessor: Class/Accessor, for an efficiency
comparison.

AUTHOR
======

   Michael G Schwern <schwern@pobox.com>

SEE ALSO
========

   *Note Class/Accessor: Class/Accessor,


File: pm.info,  Node: Class/Autouse,  Next: Class/BlackHole,  Prev: Class/Accessor/Fast,  Up: Module List

Defer loading ( 'use'ing ) of a class until run time
****************************************************

NAME
====

   Class::Autouse - Defer loading ( 'use'ing ) of a class until run time

SYNOPSIS
========

     use Class::Autouse;
     
     Class::Autouse->autouse( 'CGI' );
     
     print CGI->header();

DESCRIPTION
===========

   Class::Autouse allows you to specify a class the will only load when a
method of the class is called. For large classes that might not be used
during the running of a program, such as Date::Manip, this can save you
large amounts of memory, and decrease the script load time.

AUTHOR
======

   Adam Kennedy, cpan@ali.as

SEE ALSO
========

   autoload


File: pm.info,  Node: Class/BlackHole,  Next: Class/Class,  Prev: Class/Autouse,  Up: Module List

base class to treat unhandled method calls as no-ops
****************************************************

NAME
====

   Class::BlackHole - base class to treat unhandled method calls as no-ops

SYNOPSIS
========

     use Class::BlackHole;

     # set up a class X, to inherit from Class::BlackHole
     @X::ISA = qw(Class::BlackHole);
     # put a method in it
     sub X::zaz { 123123; }
     
     print "Zaz is <", X->zaz, ">\n";
     print "Flork is <", X->flork, ">\n";
     print "can zaz : <", X->can('zaz'), ">\n";
     print "can flork : <", X->can('flork'), ">\n";
     
     
     The above code prints:
      Zaz is <123123>
      Flork is <>
      can zaz : <CODE(0x392c7d4)>
      can flork : <>

DESCRIPTION
===========

   Normally, if you try to call a method that there's no handler for, you
get an error:

     Can't locate object method "flork" via package "X".

   But for classes that inherit from Class::BlackHole, unhandled methods
become just no-operations.

CAVEATS
=======

   Be sure to have Class::BlackHole be the absolute last item in your
class's ISA list.

   This class will almost definitely not work right as part of any ISA
tree that has multiple inheritance.

IMPLEMENTATION
==============

   Class::BlackHole just traps everything with an AUTOLOAD sub that is a
no-operation.

   HOWEVER, what makes Class::Blackhole different than merely:

     @Class::BlackHole::ISA = ();
     sub Class::BlackHole::AUTOLOAD { }

   is that this would (unhappily) trap calls to the helpful methods in
UNIVERSAL, like can, VERSION, and isa.  Class::BlackHole aliases those
methods (or better said, all subs in package UNIVERSAL) into its own
package, so that they'll be accessible instead of being caught by the
AUTOLOAD.

FUNCTIONS AND METHODS
=====================

   This module provides no functions or methods.

   It exports no symbols into the calling package or anywhere else.

DISCLAIMER
==========

   This program is distributed in the hope that it will be useful, but
*without any warranty*; without even the implied warranty of
*merchantability* or *fitness for a particular purpose*.

   But let me know if it gives you any problems, OK?

COPYRIGHT
=========

   Copyright 1999, 2000, Sean M. Burke `sburke@cpan.org', all rights
reserved.  This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.

AUTHOR
======

   Sean M. Burke `sburke@cpan.org'


File: pm.info,  Node: Class/Class,  Next: Class/Classgen/Attribute,  Prev: Class/BlackHole,  Up: Module List

Adds data members to Perl packages
**********************************

NAME
====

   Class::Class - Adds data members to Perl packages

SYNOPSIS
========

   In module MyModule.pm:

     package MyModule;
     use Class::Class;
     @ISA = qw (Class::Class);

     %MEMBERS =
       (scalar_ => '$', # "scalar" is a keyword
        scalarref => '\$',
        array => '@',
        arrayref => '\@',
        hash => '%',
        hashref => '\%',
        glob => '*',
        globref => '\*',
        object => 'Some::Package',
        objectref => '\Some::Package');

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

     # object initialization goes here: DO NOT USE 'new'

     return $self;
       }

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

     # object cleanup (if any) goes here: DO NOT USE 'DESTROY'

     return $self;
       }

   In other files which wish to use MyModule:

     use MyModule;

     my $mm = new MyModule;

     $mm->scalar_ (42); # set "scalar_" to 42
     $mm->scalar_ ( ); # get value of "scalar_"
     $mm->scalarref (1.1); # set "scalarref" to 1.1
     $mm->scalarref ( ); # get reference to value of "scalarref"

     $mm->array ( ); # get arrayref stored in "array"
     $mm->array (1); # get 2nd element of "array"
     $mm->array (1, 'fish'); # set 2nd element of "array" to 'fish'
     $mm->arrayref ( ); # get arrayref stored in "arrayref"
     $mm->arrayref (1); # get reference to 2nd element of "arrayref"
     $mm->arrayref (1, 'fish'); # set 2nd element of "arrayref" to 'fish'

     $mm->hash ( ); # get hashref stored in "hash"
     $mm->hash ('bob'); # get 'bob' element of "hash"
     $mm->hash ('bob', 'one'); # set 'bob' element of "hash" to 'one'
     $mm->hashref ( ); # get hashref stored in "hashref"
     $mm->hashref ('bob'); # get reference to 'bob' element of "hashref"
     $mm->hashref ('bob', 'one'); # set 'bob' element of "hashref" to 'one'

     open G, '<blah.txt';
     $mm->glob (*G); # set "glob" to *G
     $mm->glob ( ); # get value of "glob"
     use Symbol;
     $mm->globref (gensym); # set "globref" to anonymous symbol
     $mm->globref ( ); # get reference to value of "globref"

     $mm->object ( ); # get object in "object"
     $mm->object->method; # invoke method on object in "object"
     $mm->objectref ( ); # get reference to object in "objectref"

DESCRIPTION
===========

   *Class::Class* implements inheritable data methods for your packages
with the same rules of inheritance as your other methods by generating
creating accessor methods for your data the first time you make an
instance of your package.

   Why reinvent the wheel, you say?  I got tired of the way Class::Struct
worked, since the methods weren't inheritable the way I expected (no
initialization of parent members before child members, for example), it
was invoked programatically rather than declaratively, and I wanted to
learn more about globs and the like.  Plus I have a big head.  :-)

Using Class::Class Modules
--------------------------

   Using *Class::Class* modules is very simple.  Just inherit from them as
normal, but don't bother with writing a new method - *Class::Class*
provides one for you that arranges for superclasses to be initialized
before subclasses.  It also takes multiple inheritance into account
(correctly, I hope).

   To initialize your package, instead of `sub new', write a `sub
initialize' which takes an instance of your package as its only argument,
and returns an instance:

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

     # Do something clever here with your object...

     return $self;
       }

   There is no requirement you return the same instance that was handed to
you.  The methods `polymorph' and `polyvolve' are provided for this very
purpose, to help with "virtual constructors".

Writing Class::Class Modules
----------------------------

   Writing *Class::Class* modules is straight-forward.

Polymorph and Polyvolve
-----------------------

`polymorph'
`polyvolve'
EXAMPLES
========

Using Class::Class Modules
--------------------------

  1. Simple use:

Writing Class::Class Modules
----------------------------

  1. Setting a package global:

SEE ALSO
========

   *Note Class/ISA: Class/ISA,

   *Class::ISA* creates an inverted inheritance tree, permitting easy
traversal of a packages entire inheritance.

DIAGNOSTICS
===========

   The following are the diagnostics generated by *Class::Class*.  Items
marked "(W)" are non-fatal (invoke `Carp::carp'); those marked "(F)" are
fatal (invoke `Carp::croak').

Not a class or subclass of '%s'
     (F) The caller tried to assign to an object data member something
     which isn't an instance of that object's class, or which isn't an
     instance of a derived class.

No coderef defined for '%s' yet
     (F) The caller tried to use a code reference without first providing
     assigning a coderef to the member.

BUGS AND CAVEATS
================

   Presently, *Class::Class* uses hashes for data members; array are
demonstrably better for several reasons (see XXX - *TPJ*) if you don't
need direct access to data members by name.  And even if you do, fields
shows a good way to do that with recent versions of Perl.

AUTHORS
=======

   B. K. Oxley (binkley) at Home <binkley@bigfoot.com>

COPYRIGHT
=========

     Copyright 1999, B. K. Oxley (binkley).

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


File: pm.info,  Node: Class/Classgen/Attribute,  Next: Class/Classgen/Classgen,  Prev: Class/Class,  Up: Module List

generates all get- and set-methods for new classes created by classgen.
***********************************************************************

NAME
====

   Attribute.pm - generates all get- and set-methods for new classes
created by classgen.

VERSION
=======

   3.03

SYNOPSIS
========

   Within classgen called as:

     use Attribute;			# work with object Attribute
     my $attr = Attribute->new();	# derive a new Attribute instance $attr

   Let Ex.pm be a generated class, with internal variables $var, %entry
and @list:

     use Ex.pm;			# use generated class
     my $ex=Ex->new();		# creating a new object
     $ex->set_var('this is a test');	# setting instance variable $var
     $ex->set_h_entry( 12, twelve );	# like $entry{12}='twelve'
     $ex->set_h_entry( 60, sixty );	#
     $ex->set_l_list( 3, -100 );	# like $list[3]=-100;
     $x=$ex->get_var();		# like $x=$var;
     $x=$ex->get_h_entry(12);
     @keys=$ex->get_keys_h_entry();	# get all keys of internal %entry
     etc.

DESCRIPTION
===========

   It is good OOP-style to access and manipulate instance variables of a
class NEVER by a direct call, but via appropriate methods. You should
always follow this concept to avoid problems when inheriting from your
object oriented code.

   classgen has been designed for exactly this purpose: To have all
necessary methods available for all instance variables. Right from the
start.

General syntax for generated methods
------------------------------------

   The methods name itself should uniquely identify the type of instance
variable accessed or modified. So the general method convention is:

   * methodname_scalarname to work on a scalar instance

   * methodname_h_hashname to work on a hash instance

   * methodname_l_listname to work on a list instance

   With this convention you will always know what to expect, e.g.:

     use Example;
     $ex = Example->new();
     ...
     print $ex->get_number;		# access instance variable $number
     print $ex->get_l_cities;	# access instance variable @cities
     print $ex->get_keys_h_country;	# get keys of inst.var. %country

   For %hashes and @lists it is sometimes necessary to access the
reference of the instance variable. Then use:

   * methodname_rh_hashname to find the reference of a %hash instance

   * methodname_rl_listname to find the reference of a @list instance

   Some other methods deviate from these rules when purpose and involved
type of instance variable are self evident. See below.

Generated methods for $scalars
------------------------------

   For all $scalar instance variables in classgens control file
Attribute.pm generates (the phrase 'scalar' is replaced by the actual name
of the $scalar instance variable):

   * clear_scalar(): generated clear() method for $scalars

   * get_scalar(): generated accessor method for $scalars

   * set_scalar($value): generated manipulator for $scalars

Example: control file contains $var of class Example.
-----------------------------------------------------

   Attribute generates clear_var(), get_var() and set_var. Class Example
can be used like:

     use Example;	# use object Example
     use strict;	# recommended

     my $ex = Example->new();	# creating a new Example instance
     $ex->clear_var();		# set $var in Example to undef
     $ex->set_var( "what a wonderful day" );

     print $ex->get_var();

Generated methods for %hashes
-----------------------------

   For all %hash instance variables in classgens control file Attribute.pm
generates (the phrase 'hash' is replaced by the actual name of the %hash
instance variable):

   * clear_h_hash(): generated clear() method for %hashes

   * delete_h_hash_at($key): deletes $key from internal %hash.

   * get_h_hash(): generated accessor to the %hash itself

   * get_h_hash_at($key): generated key-based accessor to %hash

   * get_keys_h_hash(): generated key-accessor for %hashes

   * get_rh_hash(): generated accessor to \%hashes

   * set_h_hash($key, $value): generated manipulator for %hashes

Generated methods for @lists
----------------------------

   For all @list instance variables in classgens control file Attribute.pm
generates (the phrase 'list' is replaced by the actual name of the @list
instance variable):

   * clear_l_list(): generated clear() method for @lists

   * get_list_at($index): generated indexed-accessor for @lists

   * get_l_list(): generated list-accessor for @lists

   * get_rl_list(): generated accessor to \@lists

   * pop_list(): generated pop-accessor for @lists

   * push_list($value): generated push-manipulator for @lists

   * set_l_list($index, $value): generated manipulator method for @lists

Internal methods
----------------

   A few methods are needed to provide all this:

   * sub new: constructor

   * sub get_type: to determine type of instance variable

   * sub get_var: access instance-variable

   * sub generate_blessed_h: for blessing an anonymous hash

   * sub generate_key: used to define appropriate method names

   * sub name: generate a standard name

   * sub simplify_var: to remove '^[\$%@]_+'

   * sub set_var: manipulate instance-variable

ENVIRONMENT
===========

   Nothing special. Just use Perl5.

DIAGNOSTICS
===========

   There is no special diagnostics. Attribute.pm is used within classgen
which is called with the -w option.

BUGS
====

   No bugs known.

FILES
=====

   Please refer to classgen.

SEE ALSO
========

   perldoc classgen

AUTHOR
======

   Name:  Michael Schlueter email: mschlue@cpan.org

COPYRIGHT
=========

   Copyright (c) 2000, Michael Schlueter. All Rights Reserved. This module
is free software. It may be used, redistributed and/or modified under the
same terms as Perl itself.


File: pm.info,  Node: Class/Classgen/Classgen,  Next: Class/Classgen/Comments,  Prev: Class/Classgen/Attribute,  Up: Module List

script that generates a class-module from a control file.
*********************************************************

NAME
====

   classgen - script that generates a class-module from a control file.

VERSION
=======

   3.03

SYNOPSIS
========

   !!! A fake-module, just to make the documention in the classgen-script
visible to CPAN !!!

   classgen input.txt Output.pm	# generate new class

   perldoc Output.pm	# review the fresh pod-skelton

   vi Output.pm		# edit specific methods

   less Output_gs.pm	# instance methods get-/set-

   For historical reasons the synonym ".gs" is still inthis documentation.
Please read it as "<file>_gs.pm".

DESCRIPTION
===========

   You specify the required instance-variables of a desired class by a
control-file.

   Classgen then creates a new package for you which contains the
new()-method, accessor- and manipulator-methods for all instance-variables
of that class. All instance-variables are blessed into an anonymous hash
{}.

   classgen adds a basic, simple perldoc skelton to support your
documentation for new classes.

   For a better overview version 3.03 splits the package into a .pm and a
.gs file. The .gs file contains all standard get-/set-methods and will be
reviewed only on occasion. The .pm will focus on the specific methods
only. Printouts will become much shorter and your overview will increase.

Input format of the control file
--------------------------------

   The control file is an ASCII-file which must contain the 3 sections
with specific keywords in the specified order:

     header:
     variables:

   classgen will scan for these 2 sections and act accordingly. classgen
will insist on using exactly these section-headers. It will die, if you
don't.

   * *header:* In this section you can put any Perl statement you need.
     classgen will simply copy this section to the beginning of your
     output file. You should at least include *package
     Your_Class_Name_here; use strict;*

   * *variables:* In this section you specify all your required
     instance-variables. classgen will determine the required type from
     the first character ($,@ or %) and will create all required
     variable-related methods for you. - For your convenience and to
     nurture self-documentation of your new class you can add some
     descriptive comments after the variable, just using a #.

Methods generated
-----------------

   classgen generates accessor- and manipulator-methods as required by the
variables type. The order of methods is:

   * new-method

   * specifc methods (to be extended by the user)

   * accessor methods

   * manipulator methods

   * (perldoc-skelton) (to be extended by the user)

   The *specific()* method is intended for copy&paste operation to easily
append the generated class with more specific class-methods by the user.

   A variable-name consists of <type><var_name>, with <type>=($,@,%). Via
<type> methods are generated as:

     <method name><var_name>

   Run *perldoc Attribute.pm* for an overview of all created methods.

Missing Methods for the created Objects
---------------------------------------

   A *serialize()* method should be added. So far my personal lack of
knowledge in this subject prevented me from supplying you with one. Conway
examines some possibilities, which you can find at CPAN.

Other Objects involved
----------------------

   classgen will use instances from the

   * New.pm - Object

   * Attributs.pm - Object

   * Section.pm - Object

   * Comment.pm - just a package, not an object. Cf. perldoc Comment.pm

Subroutines used by classgen
----------------------------

   Internal methods:

   * check_of_sections: to ensure every needed section is there

   * clean_up: to remove \t and other whitespaces

   * find_section: use this to use correct keywords

   * get_sections: to retrieve sections from input file

   * init_attributes : to generate Attribute-instances for all variables

   * init_new: to initialize the New-instance

   * write_begining : to write the first few lines into the new class

   * write_end :  code at the end of the new class

   * write_methods: to generate all required methods for each variable

   * write_new: to write the new-function of the generated class

How to use classgen
-------------------

   In version 3.03 an archive functionality has been introduced. Before
classgen creates the .pm and the .gs files from the control file, the old
files are copied into the /archive directory with an increasing numeriacl
starting index. So your previous edits are not lost.

   * FIRST RUN: Simply create a control file somewhere and create the
     output file where appropriate (e.g. classgen /controls/example
     /Objects/Example.pm).

   * ADDITIONAL RUNS: Classgen copies the current versions of .pm and .gs
     into the /archive directory. Next, it overwrites the current .pm and
     .gs as indicated by your control file.

   * ADDING METHODS: Edit your newly created package (e.g. Example.pm).
     Use the dummy-method at the end to create all further required
     methods of your class. All accessor- and manipulator-methods should
     already be there (I hope :-)

   * REMOVING METHODS: Cut them with your editor from the newly created
     package (e.g. Example.pm) or put comments at every line of the
     undesired subroutine. Perhaps you want to use them later again? Then
     cut them first and paste them to an intermediate-file.

   * RESTORING REMOVED METHODS: You have several choices: re-run classgen
     to create a safe copy of your package (e.g. Example_new.pm);
     copy&paste the missing part. Or re-use the intermediate-file from the
     previous hint; retrieving it from one of the files in the /archive
     directory etc.

How to produce undesired results (and how to avoid them)
--------------------------------------------------------

   Version 3.03: Problems from overwriting have been removed. Your edits
are copied to the /archive directory first.

How to handle inheritance of classes
------------------------------------

   Derive two classes with classgen. In the header-section of the derived
class you can add the required Perl-statements already in the control-file.

   Make sure to include the base-class in an @ISA-statement and adapt the
call to inherit_from() right after the blessing in the new() method of
your derived class.

   See also   examples/inheritance/README

Open issues
-----------

   I would like to know how classgen performs compared to other approaches
to object-oriented-implementations. How can I find out how much memory my
version actually consumes? - Please, gimme a hint ...

   Instance-variables could also be blessed into [] or $. Initially I
planned to offer these choices, too. It turned out to be more convenient
to omit this for a start. Your benefit is that you can do less things
wrong. As a by-product the control file becomes more handy ;-)

Background / Motivation
-----------------------

   J.Rumbaughs "Object Oriented Modelling" showed me a very promissing way
to tackle challenging software-projects. The idea is to identify relevant
classes (objects), their relationship (associations), their dynamic
behaviour (statediagrams) and their flow of data (functional model) - all
on paper.

   Once done and tested by various scenarios a very good specification has
been grown. Then there are ways to implement these objects both in
object-oriented (e.g. C++, Smalltalk, Eiffel) and NON-object-oriented
languages (e.g. C, Fortran, Algol) or databases. - What a challange for
Perl!

   I tried Damian Conways excellent book "Object Oriented Perl", which has
been published in fall 1999. I learned again, that there still "... are
always more than one way to do it" when it comes to implementing objects
in Perl:

   * do it by hand: introduce a new instance-variable and write all
     required methods to acces or change this variable yourself.

   * use the AUTOLOAD-mechanism to provide all required get- and
     set-methods at run-time.

   * use class-templates, like Class::Struct or Class::MethodMaker.

   Clearly, the first choice is the least desireable one. It is prone to
typing errors and one spends more time on same methods again rather than
on methods unique to the class (as I would prefer).

   The other methods have some advantages and some disadvantages. The
least tasty for me was that they tend to produce "obscure" code, at least
in examples I looked at. That is, code where I had to spend a lot of
thinking to understand what it does.

   Rather, I'd prefer code which I can understand at just one glance
(idealy ;-). Therefor classgen creates almost every get- and set-method
you can think of. Should you need it, it is already there. Should you
dislike it, simply throw methods away. Or even better, just do not care
about their existence at all. Stay focused on what your class should be
doing, not on the instance-variables.

   There is another inportant reason for my approach. I feel OOP-code
appears to be more 'cleaner' when it can be distributed over separated,
individual files. Some of the approaches mentioned above tend to create
and modify objects WITHIN another program. I think that shouldn't be done.
Have a look at my 'peanuts' example.

Future Plans
------------

   classgen lets me create new classes within minutes rather than days. I
myself am quite satisfied with the current performance. classgen was
created more or less on-the-fly. Perhaps I will redesign it by a more
consequent OMT-approach lateron.

   But before doing so I'd need more input about the good's and bad's from
you to make up my mind.  The missing parts. The nice-to-have things and so
on.

   If you like classgen and want it to have more useful functions please
let me know ;-)

ENVIRONMENT
===========

   Perhaps you may have to modify the first line in classgen due to
different locations of perl on different operating systems. If so, you'll
probably find classgen as (watch make install for details):

     /usr/bin/classgen

   You can avoid this adaption if you simply call:

     perl classgen <input_file> <output_class>

DIAGNOSTICS
===========

   When running classgen you will see the message:

     #: 2
     var1head1
     N: 2

   which is a relict from program development. It helped me to trace if
the correct sections where identified. It does not harm very much and
perhaps may be useful to find errors lateron. So, for the moment, it is
just in the program.

   classgen runs with the -w option. If you call classgen with the wrong
number of arguments it will simply die. The subroutines should either
return your requested result or "undef".

   The ideal diagnostics is the diagnostic which is not there, but which
function is performed. - To approach this ideal I did the following:

   The sensitivity analysis part from the Taguchi-method has been used to
measure sensitivity of classgen against errorness inputs from the control
file (that is against variable usage-conditions). Only those kinds of
errors which are likely to occure for a serious user, playing by the
rules, where investigated. Those are for example:

   * missing ; in the header section (no problem, but perl will complain
     lateron; this is somewhat inconvenient)

   * putting , or ; after a variable from the variables: section (causing
     strange methods generated)

   * putting comments in all sections (not allowed in the early version,
     but very useful for self-documentation purposes)

   This lead to creating the Comments.pm package, which provides just a
few simple routines to detect and to correct the errors mentioned above.

Error Messages:
---------------

   In alphabetical order:

   * 'less sections than expected' - not all sections could be found -
     check if delimiter ':' has been used ( from: check_of_sections() )

   * 'more sections than expected' - there are more sections specified
     than allowed - check for multiple sections or not allowed sections (
     from: check_of_section() )

   * 'specified identifier $id is ambigous' - more than one section is
     found in the control file with the same name - check the control file
     for unique sections ( from: find_section() )

   * 'specified identifier $id not found in %section' - this section is
     missing in the control file - add this section to the control file (
     from: find_section() )

BUGS
====

   You should always put at least one instance-variable into your class.
If you don't, you'll get a strange blessing ;-) . In most cases you
probably will do so automatically, so I decided to leave this
invonvenience until I know if it is worth while to re-concept classgen or
not (cf. Future Plans).

FILES
=====

Installation
------------

   Copy the .gz to a suitable directory. Run 'gunzip' and 'tar xvf '.
Change to Class/Classgen. Execute:

     perl Makefile.PL
     make

   As root do the final installation:

     make install

   When you run Perl under Windows you may want to use nmake.exe instead
of make (download e.g. from
ftp://ftp.microsoft.com/Softlib/MSLFILES/nmake15.exe)

SEE ALSO
========

     Changes

Methods created by classgen
---------------------------

   Run 	perldoc Attribute.pm

   Run 	perldoc New.pm

Example: Starting up with classgen
----------------------------------

   You may also want to review the included example files, which creates
the class Example.

   * control.txt is the control-file for the class Example

   * Example.pm is the result created by classgen

   * 'classgen control.txt Example.pm' will create Example.pm

perldoc
-------

   Please refer also to

   * perldoc New.pm (specifics of the created $self->new() function)

   * perldoc Attribute.pm (type dependend functions)

   * perldoc Section.pm (splitting up the control file)

   * perldoc Comments.pm (dealing with comments)

Books I referred to
-------------------

   * J.Rumbaugh, *Objektorientiertes Modellieren und Entwerfen*, ISBN
     3-446-17520-2  or J.Rumbaugh *Object-Oriented Modeling and Design*,
     ISBN 0136298419

   * D.Conway, *Object Oriented Perl*, ISBN 1-884777-79-1

AUTHOR
======

   Name:  Michael Schlueter email: mschlue@cpan.org

COPYRIGHT
=========

   Copyright (c) 2000, Michael Schlueter. All Rights Reserved. This module
is free software. It may be used, redistributed and/or modified under the
same terms as Perl itself.


File: pm.info,  Node: Class/Classgen/Comments,  Next: Class/Classgen/New,  Prev: Class/Classgen/Classgen,  Up: Module List

To keep some nasty errors from users of classgen.
*************************************************

NAME
====

   Comments.pm - To keep some nasty errors from users of classgen.

VERSION
=======

   3.03

SYNOPSIS
========

   Used within classgen.

DESCRIPTION
===========

   Comments.pm checks for missing ';' in the header section. Missing ';'
will allow to run classgen smoothly but lateron perl will complain about
this error. Those anoying problems should be kept from the user.

   It turned out to be useful to add some elucidating comments after
variables in the variables-section. This increases self-documentation of
the source code and better documents intentions. Variables are simply
listed in the variables section. But user may tend to put a syntactically
';' or ',' after each variable. Again, classgen would run smoothly but
give nasty error messages lateron from perl. All these anoying problems
should be kept from the user.

ENVIRONMENT
===========

   Nothing special. Just use perl5.

DIAGNOSTICS
===========

   There is no special diagnostics. New.pm is used within classgen which
is called with the -w option.

BUGS
====

   No bugs known.

FILES
=====

   Please refer to classgen.

SEE ALSO
========

   perldoc classgen

AUTHOR
======

   Name:  Michael Schlueter email: mschlue@cpan.org

COPYRIGHT
=========

   Copyright (c) 2000, Michael Schlueter. All Rights Reserved. This module
is free software. It may be used, redistributed and/or modified under the
same terms as Perl itself.


File: pm.info,  Node: Class/Classgen/New,  Next: Class/Classgen/Section,  Prev: Class/Classgen/Comments,  Up: Module List

Creates the new() method for classes generated by classgen.
***********************************************************

NAME
====

   New.pm - Creates the new() method for classes generated by classgen.

VERSION
=======

   3.03

SYNOPSIS
========

   Used within classgen.

DESCRIPTION
===========

   The main purpose of New.pm is to write the new() method for a class
generated by classgen. It provides code to derive local instance variables
with 'my' for all specified instance variables. It provides code to store
them within an anonymous hash (only way in the current version). Finally,
this hash is blessed into the desired class.

Methods generated by New.pm
---------------------------

   In the blessing section of the generated new() method:

   * inherit_from(): copies the entries of the blessed {} from the base
     class into the blessed {} of the derived class.

ENVIRONMENT
===========

   Nothing special. Just use Perl5.

DIAGNOSTICS
===========

   There is no special diagnostics. New.pm is used within classgen which
is called with the -w option.

BUGS
====

   No bugs known.

FILES
=====

   Please refer to classgen.

SEE ALSO
========

   perldoc classgen

AUTHOR
======

   Name:  Michael Schlueter email: mschlue@cpan.org

COPYRIGHT
=========

   Copyright (c) 2000, Michael Schlueter. All Rights Reserved. This module
is free software. It may be used, redistributed and/or modified under the
same terms as Perl itself.


File: pm.info,  Node: Class/Classgen/Section,  Next: Class/Classless,  Prev: Class/Classgen/New,  Up: Module List

Identifies the diffferent sections from classgens control file.
***************************************************************

NAME
====

   Section.pm - Identifies the diffferent sections from classgens control
file.

VERSION
=======

   3.03

SYNOPSIS
========

   Used within classgen.

DESCRIPTION
===========

   Section.pm is needed to administer the information found in the control
file of classgen for later use.

ENVIRONMENT
===========

   Nothing special. Just use Perl5.

DIAGNOSTICS
===========

   There is no special diagnostics. Section.pm is used within classgen
which is called with the -w option.

BUGS
====

   No bugs known.

FILES
=====

   Please refer to classgen.

SEE ALSO
========

   perldoc classgen

AUTHOR
======

   Name:  Michael Schlueter email: mschlue@cpan.org

COPYRIGHT
=========

   Copyright (c) 2000, Michael Schlueter. All Rights Reserved. This module
is free software. It may be used, redistributed and/or modified under the
same terms as Perl itself.


File: pm.info,  Node: Class/Classless,  Next: Class/Contract,  Prev: Class/Classgen/Section,  Up: Module List

framework for classless OOP
***************************

NAME
====

   Class::Classless - framework for classless OOP

SYNOPSIS
========

     use strict;
     use Class::Classless;
     my $ob1 = $Class::Classless::ROOT->clone;
     $ob1->{'NAME'} = 'Ob1';
     $ob1->{'stuff'} = 123;
     $ob1->{'Thing'} = 789;
     
     my $ob2 = $ob1->clone;
     $ob2->{'NAME'} = 'Ob2';
     
     printf "ob1 stuff: <%s>\n", $ob1->{'stuff'};
     printf "ob2 stuff: <%s>\n", $ob2->{'stuff'};
     printf "ob1 Thing: <%s>\n", $ob1->{'Thing'};
     printf "ob2 Thing: <%s>\n", $ob2->{'Thing'};
     
     $ob1->{'METHODS'}{'zaz'} =  sub {
        print "Zaz! on ", $_[0]{'NAME'}, "\n";
     };
     
     $ob1->zaz;
     $ob2->zaz;
     $ob1->EXAMINE;
     $ob2->EXAMINE;

   This prints the following:

     ob1 stuff: <123>
     ob2 stuff: <123>
     ob1 Thing: <789>
     ob2 Thing: <>
     Zaz! on Ob1
     Zaz! on Ob2
     <Class::Classless::X=HASH(0x200236f4)>
        'stuff', 123,
        'NAME', 'Ob1',
        'Thing', 789,
        'METHODS', { 'zaz', 'CODE(0x20068360)' },
        'PARENTS', [ 'ROOT' ],
     <Class::Classless::X=HASH(0x2002cb48)>
        'stuff', 123,
        'NAME', 'Ob2',
        'METHODS', {  },
        'PARENTS', [ 'Ob1' ],

DESCRIPTION
===========

   In class-based OOP frameworks, methods are applicable to objects by
virtue of objects belonging to classes that either provide those methods,
or inherit them from classes that do.

   In classless OOP frameworks (AKA delegation-and-prototypes frameworks),
what methods an object is capable of is basically an attribute of that
object.  That is, in Perl terms: instead of methods being entries in the
symbol table of the package/class the object belongs to, they are entries
in a hash table inside the object.  Inheritance is implemented not by
having classes inheriting from other classes (via ISA lists), but by
having objects inherit from other objects (via PARENTS lists).

   In class-based OOP frameworks, you get new objects by calling
constructors.  In a classless framework, you get new objects by copying
("cloning") an existing object - and the new clone becomes a child
(inheritor) of the original object.  (Where do you get the one original
object?  The language provides one, which has no parents, and which
contains some general purpose methods like "clone".)

WHAT'S IN AN OBJECT
===================

   Each classless object is a reference to a hash, containing:

   * an entry 'PARENTS', which is a reference to a list of this node's
parents.  (For ROOT, this will be an empty list; for most nodes, there
will be just one item in this list; with multiple parents, you get
multiple inheritance.)

   * An entry 'NAME', which is initialized to a unique value (like "x_11")
when the object has just been created by cloning.  The 'NAME' attribute is
not required, and deleting it is harmless.

   * An entry 'METHODS', which is a reference to a hash that maps method
names (e.g., "funk") to coderefs or to constant values.  When you call
$foo->funk(@stuff), Class::Classless's dispatcher looks to see if there's
a $foo->{'METHODS'}{'funk'}.  If so, and if it's a coderef, then that
coderef is called with ($foo, $callstate, @stuff) as its parameter list
(See the section "What A Method Sees", below, for an explanation of this).
If there's a $foo->{'METHODS'}{'funk'} and it's not a coderef, then the
value is returned, possibly with automagical dereferencing.  (See the
section "Constant Methods", below.)  But, finally, if there is no such
method, Class::Classless's dispatcher looks in $foo's parent to see if
there's a $foo_parent->{'METHODS'}{'funk'}, and so on up the inheritance
tree.  If no 'funk' method is found in $foo or any of $foo's ancestors,
Class::Classless dies with an error to that effect.  (But see the section
on the NO_FAIL attribute, below.)

   * Anything else you want to put in the hash.  I provide no inherent
mechanism for accessing attributes (unlike, say, Self, which can
automagically treat method calls as accessors, roughly speaking), so
you're down to setting with $a->{'foo'} = VAL, reading with $a->{'foo'},
and possibly testing for the attribute with an exists($a->{'foo'}).
(However, do have a look at the `get_i', `set_i', and `exists_i' methods,
below.)

METHODS IN ROOT
---------------

   ROOT provides various methods you might find helpful:

   * $thing->clone - makes a new object based on an existing one.  The
only way you get to produce new objects is to clone existing ones.
Existing objects are either clones of ROOT, or clones of clones of ROOT,
and so on.  A newly cloned object has a copy of all its parent's
attributes whose names don't match /^[A-Z]/s (i.e., that don't begin with
a letter between ASCII capital A and ASCII capital Z, inclusive).  The new
object is then initialized with a per-session-unique name like "x_12"; its
PARENT attribute is set to a list containing its one parent; and its
'METHODS' attribute is set to an empty hash.  (Note that the copying of
parent attributes is not a deep copy - the parent has foo => [bar, baz],
then the child will have a reference to that same list, not a copy of that
list!)

   (Also, if $thing->is_lineage_memoized is true, the clone will have a
memoized lineage too.  And note that $Class::Classless::ROOT has lineage
memoization off.  See the description of "$thing->memoize_lineage", below,
for a description of what this all means.)

   * $thing->polyclone($thing2, $thing3...) - makes a new object based on
$thing, $thing2, $thing3, etc.  Attributes in $thing overrride those in
$thing2, and so on.  The PARENTS list will consist of $thing, $thing2,
$thing3, etc., in that order.  Also, if $thing->is_lineage_memoized is
true, the clone will have a memoized lineage too.

   * $thing->get_i('attrib') - ("get, with inheritance").
$thing->get_i('foo') returns the value of the 'foo' attribute for $thing.
If there is no $thing->{'foo'}, it looks for a 'foo' attribute in each of
$thing's ancestors.  Returns the first one found.  If none are found,
returns undef.  (But note that undef could result if $thing->{'foo'} or
$some_parent->{'foo'} is undef.)

   * $thing->exists_i('attrib') - ("exists, with inheritance").
$thing->exists('foo') returns true if either $thing or any of its
ancestors contains a 'foo' attribute (as tested with simply
exists($node->{'foo'})).  Otherwise, returns false.

   * $thing->put_i('attrib', VALUE) - ("put, with inheritance").  put_i
looks across $thing and its ancestors, and for the first one that contains
an 'attrib' attribute, sets its value to VALUE, and then returns VALUE.
If neither $thing nor any of its ancestors contain a 'attrib' attribute,
this will set $thing->{'attrib'} = VALUE and return VALUE, but will warn
(via carp) if $^W (warnings, usually from giving Perl a -w switch) is true.

   * $thing->EXAMINE - prints a somewhat simpleminded dump of the contents
of the object.  Like a cheapo version of Data::Dumper's Dump() function.

   * $thing->FLATTEN - deletes all attributes (and their values) in the
object whose names do not match /^[A-Z]/s (i.e., whose names don't begin
with a letter between ASCII capital A and ASCII capital Z, inclusive).
You can use this if you don't need an object's data, but don't feel bold
enough to destroy it, because it may have clone-children that would be
orphaned (a bad thing) if this node lost its PARENT attribute, say.

   * $thing->allcan('baz') - returns the list (in order) of all 'baz'
methods in $thing's ISA tree.  This may be an empty list.  (Note that the
NO_FAIL attribute has no effect on the allcan method.)  Note especially
that the magic dereferencing magic for constant method values is not
triggered.  That is, what allcan('baz') returns is simply a list of the
values of $x->{'METHODS'}{'baz'} wherever such a METHODS entry exists, for
all objects in $thing's inheritance tree.

   * $thing->howcan('baz') - just like allcan, but the list returned
consists of pairs of values, where each pair consists of 1) the object
that provides the 'baz' method, followed by 2) the value it provides for
that method.  (Remember that that value may be a coderef, or it may be any
kind of other reference (which will not be magically resolved as it would
have been by the dispatcher - see the section "Constant Methods", or it
may be any nonreference scalar value - including 0 or undef!)  The pairs
are in order.  You can read this list into a hash that maps from the
methods to the method-values, but of course then you lose the ordering.

   * $thing->can('baz') - if $thing is capable of the method 'baz', this
returns true, otherwise it returns false.  Do not try to override the can
method.  (Note that the NO_FAIL attribute has no effect on the can
method.)  Note also that this does NOT return the method's value, as it
did in the first version of Class::Classless, which (like Perl's normal
object system) would return the (coderef) value of the method 'baz' for
the first object in $thing's tree that provided such a method.

   That worked then, since all method values under the first version of
Class::Classless had to be coderefs (which were, of course, true in a
boolean context).  However, now that a Class::Classless method have have a
constant value that is false, having can() return that value would be
indistinguishable from having it return any false value meant as a signal
the object incapable of the method.  In short, can() simply has to return
either true or false now.  If you need the value of the methods, use
allcan() or howcan().

   * $thing->VERSION - same as $thing->get_i('VERSION').  Note that ROOT
has an entry of 'VERSION' => '0.00'.  Do not try to override the VERSION
method.

   * $thing->VERSION(version_number) - dies if $thing->VERSION is less
than version_number.  Otherwise returns $thing->VERSION.

   * $thing->isa($thing2) - returns true if $thing2 is in $thing's ISA
tree - i.e., if it's an ancestor of $thing.  (Also returns true if $thing2
*is* $thing.)  Otherwise returns false.  Do not try to override the isa
method.

   * $thing->ISA_TREE - returns $thing's ISA tree, linearized - i.e., the
list of nodes, in order, starting with $thing (and presumably ending with
$ROOT), that you would search thru for method calls on $thing, or get_i
calls on $thing.  Do not try to override the ISA_TREE method.

   * $thing->memoize_lineage - makes this object eligible for having its
ISA_TREE cached.  Normally, every method call on an object causes the
routine ISA_TREE to be called, so that Class::Classless knows where to
look for methods, and in what order.  You can avoid this having to happen
each time by causing the results of $thing->ISA_TREE to be memoized
(cached); then, subsequent method calls on $thing will just use the cached
linearization.  This means, however, that you must not change any of
$thing's ancestry (who its parents are, or any of its parents' parents,
etc.), or the changes will not be noticed.  (If you do want to change any
such thing, unmemoize the lineage first, as below.  Also remember that you
will need to unmemoize the lineages of all existing clones, too.)

   (The ISA_TREE cache happens to be stored in $thing->{'ISA_CACHE'}.)

   $thing->memoize_lineage has no effect if memoization is already on.
This always returns $thing, which makes it convenient for calling on newly
cloned objects:

     $thing = $foo->clone->memoize_lineage;

   Note that as described above, the normal behavior of $foo->clone is to
turn on ISA_TREE memoization for any new clones of $foo if $foo has its
ISA_TREE memoization turned on.

   * $thing->unmemoize_lineage - this turns off the above-mentioned
ISA_TREE cache for $thing.  Has no effect if lineage-memoization is
already off.  Like $thing->memoize_lineage, this returns $thing.  Think
carefully about how you use this.  It's never going to be a problem if the
only way you call it is as:

     $thing = $foo->clone->unmemoize_lineage;

   I.e., when you want a new object whose lineage you want to be free to
alter later without having to worry about caching.  (And when in doubt,
leave caching off.)

   However, note that this is wrong:

     $thing = $foo->clone->memoize_lineage;
     ...stuff...
     push @{$thing->{'PARENTS'}}, $yorp;
     $thing->unmemoize_lineage;

   ...because the 'unmemoize_lineage' call on $thing will be using an
already out-of-date cache of its old ISA_TREE.  That is likely to be
harmless, though, unless $yorp overrides the normal 'unmemoize_lineage'
method.  But this is better:

     $thing = $foo->clone->memoize_lineage;
     ...stuff...
     $thing->unmemoize_lineage;
     push @{$thing->{'PARENTS'}}, $yorp;
     $thing->memoize_lineage;

   But consider this harder case:

     $thing = $foo->clone->memoize_lineage;
     ...stuff...
     $zaz = $thing->clone; # so it will have memoization
     ...more stuff...
     $thing->unmemoize_lineage;
     push @{$thing->{'PARENTS'}}, $yorp;
     $thing->memoize_lineage;

   Even though you correctly turned off $thing's cache at the right
moment, you forgot about $zaz's cache, which was and still is out of date.

   * $thing->is_lineage_memoized - returns true iff $thing is using
lineage memoization.

   * $thing->DESTROY - this is here to trap DESTROY calls that Perl makes
when it's about to deallocate an object, either when the object's
reference count goes to 0, or at global destruction time.  Currently it's
a no-op, for many annoyingly complicated reasons.  Do not try to override
the DESTROY method!  If you don't know what DESTROY methods are for
anyway, don't worry about it.

CONSTANT METHODS
================

   I expect that most methods (i.e., things in the $foo->{'METHODS'} hash)
will be coderefs.  However, if you want the value of a method to be a
constant, I figure there's no point in making you say:

     $foo->{'METHODS'}{'funk'} = sub { 7 };

   just so $foo->funk can return the constant value 7.

   So instead, I've made it so that when you call $foo->funk, and
Class::Classless finds that $foo->{'METHODS'}{'funk'} exists, or that
$some_ancestor->{'METHODS'}{'funk'} exists, it takes that value and
decides what to do with that value, like so:

   * Unless that value (which, by the way, is free to be undef!) is a
reference, then it's a constant, so return it.  That means that if you set
$foo->{'METHODS'}{'funk'} = 7, then $foo->funk will always return 7.

   * If it's an unblessed coderef, call it with arguments as explained in
the "What a Method Sees" section, below.  Note that blessed coderefs (as
rare at they are) are not called.

   * Otherwise, it must be some sort other sort of constant to return,
which happens to be a reference.

   * If it's a reference of the class '_deref_array', then it's
array-dereferenced before being returned.  So if you wanted
$foo->band_members to return a constant list ('Ad Rock', 'MCA', 'Mike D'),
you can do it with: $foo->{'METHODS'}{'band_members'} = bless [ 'Ad Rock',
'MCA', 'Mike D'], '_deref_array'. When you call $foo->band_members then,
Class::Classless's dispatcher will basically say:
return(@{$foo->{'METHODS'}{'band_members'}});

   * If it's a reference of the class '_deref_scalar', then it's
scalar-dereferenced before being returned.  This is not as immediately and
obviously useful as the same trick with '_deref_array', but it does make
possible a few tricks.  First off, you can have something like:

     my $counter = 0;
     bless $counter, '_deref_scalar';
     $fee->{'METHODS'}{'counter_value'} = \$counter;
     $fye->{'METHODS'}{'counter_value'} = \$counter;
     $foe->{'METHODS'}{'counter_value'} = \$counter;

   to have these all share the same value, which you'd get from going
$fee->counter_value, $fye->counter_value, or $foe->counter_value.

   Second off, suppose (as unlikely as it is) you actually wanted a
constant value to be returned - but the value you want returned is an
unblessed coderef!  If you just stuck that value in $foo->{'METHODS'},
it'd get called instead of returned as a constant.  Well, you can just go:

     my $cr = sub { ...whatever... };
     $foo->{'METHODS'}{'zaz'} = bless \$cr, '_deref_scalar';

   So when you call $foo->zaz, Class::Classless sees a scalar of class
'_deref_scalar', and returns it, like return(${$foo->{'METHODS'}{'zaz'}}).
That value is, of course, your coderef.

   * And finally, if the value in $foo->{'METHODS'}{'funk'} was a
reference, but was neither an unblessed coderef, nor a reference of class
'_deref_array', nor of class '_deref_scalar', then it's just returned.

WHAT A METHOD SEES
==================

   Under Perl's normal object system, when you call

     $foo->bar($x, @y ...)

   bar's `@_' will consist of

     ($foo, $x, @y ...)

   So normally the first thing bar will do is something like:

     my($obj, $first, @rest) = @_;

   or

     my $obj  = shift @_;
     my $first = shift @_;
     my @rest = @_;

   *However*, subs called as methods by Class::Classless's dispatcher have
one extra argument; $_[1] is the "callstate", an object created every time
you call a Class::Classless object, and belonging to the class
'Class::Classless::CALLSTATE'.  Normally all you'd ever want to do with it
is say:

     $callstate->NEXT('foo', $bar, @baz)

   which is equivalent to $callstate->SUPER::foo($bar, @baz) under Perl's
normal object system.  See the section "More on NEXT".

   So, in other words, the first line of a Class::Classless method to be
called as

     $foo->bar($x, @y ...)

   would be

     my($obj, $callstate, $first, @rest) = @_;

   or the like.

SHARED DATA
===========

   I considered making some sort of mechanism for having private
attributes versus inherited attributes, but decided on just letting the
user work it out with `get_i', `set_i', and `exists_i'; onto this I added
the feature that attributes whose names start with a character in the
ASCII range `[A-Z]' (as opposed to `[a-z]', or anything else) don't get
copied by the clone method, and also aren't deleted by the `FLATTEN'
method.  That's the *complete extent* of the special treatment that
Class::Classless accords to attributes whose names start with `[A-Z]'.

   The upshot of this is that you can have something like "class data" by
just taking a generic object (i.e., one you expect to be cloned) and
setting attributes in it like

     $generic->{'Interface'} = 'Tk';

   then all clones of that attribute can effectively 'share' that value
like so...

     # send in the clones...
     $w1 = $generic->clone;
     $w2 = $generic->clone;
     $w3 = $generic->clone;
     ...etc...
     
     print $w1->get_i('Interface');  # to read it
     print $w2->get_i('Interface');  # to read it (same value)
     print $w3->get_i('Interface');  # to read it (same value)
     
     print $w2->put_i('Interface', 'VT320');  # to set it

   and even this, if this makes any useful sense:

     print $whatever->exists_i('Interface');  # to make sure it exists

   However, to repeat myself somewhat, the only reason this is shared is
that clone didn't copy the 'Interface' method when it made clones of
$generic, so calling `get_i' on any of the children so produced will find
the attribute not in the children, but will fall back on finding it in
$generic->{'Interface'}.

   But if you go and set $w1->{'Interface'} (as opposed to using `set_i'),
then $w1->get_i('Interface') will get you the value of $w1->{'Interface'},
not the value of $generic->{'Interface'}. In other words, you'd be
overriding the value you'd still be getting at with
$generic->{'Interface'}, $w2->get_i('Interface'), $w3->get_i('Interface'),
or even (uninterestingly) $generic->get_i('Interface').

   And in any case, you can really share data by virtue of the fact that
the clone method (at least, not the default clone method) doesn't do
copying of references (AKA "deep copying") - so you can just have all the
objects that you want to share data simply have a reference to a common
piece of data:

     my $bar = 123;
     $w->{'foo'} = \$bar;
     # Then any clones of $w will have a reference to that value --
     #  not to copies of it!
     # Similarly:
     $w->{'zaz'} = [5,6,7];
     $w->{'quux'} = {a => 11, b => 12};

INHERITANCE SYSTEM
==================

   If all you want is single-inheritance, you can skip this section, since
things will work as you expect: objects inherit from their parents, and so
on, all the way back to a parentless object (i.e., ROOT).

   As to how this works with multiple inheritance, consider first how
Perl's built-in mechanism for class inheritance works: first, a
depth-first search of the ISA tree, and then falling back to the class
UNIVERSAL, which is the implicit root for all classes.

   Class::Classless's system is different - consider this case:

     ROOT/UNIVERSAL
         |
         Y
        /  \
      A      X
      |      /
      B    /
       \ /
        C

   Here, Perl's depth-first search would linearize the tree (i.e., convert
it to a flat list consisting of search path) as:

     C   B   A   Y   X   Root/Universal

   However, I think this is just not the right way to do things.  The
point of X being a child of Y is so that X can have a chance to override
Y.  Perl's normal depth-first search doesn't allow that in cases like
this.  So my rule is: search over ancestors depth-first, but never search
a node until you've searched all its children (that is, children that are
still ancestors of the node you've built this tree for - any other
children are irrelevant).  So I linearize that list as:

     C   B   A   X   Y   Root/Universal

   So X does override Y.  (And Root/Universal is not a special case in the
searching rule.)

   Now, fatal errors may result with bizarre trees - namely ones with
cyclicity in them, such as: X's parents are A and B, A's parent is B, and
B's parent is A.  But in some cases Class::Classless *might* just try to
ignore the cyclic part.  So just don't make any cyclic trees, OK?

THE NO_FAIL ATTRIBUTE
=====================

   If you call $thing->zaz and there is no 'zaz' method that $thing is
capable of, then normally Class::Classless with throw a fatal error.
However, if $thing->get_i{'NO_FAIL'} is true, then a no-operation (like
sub { return; } ) simply results.

   (NO_FAIL also controls what happens if you call $thing->NEXT('zaz') and
there is no NEXT 'zaz' method; if NO_FAIL is true, a no-operation results;
otherwise, a fatal error results.  See the section "More on NEXT", below.)

   Implementationally, the way this is implemented is that when you call a
method, a routine of Class::Classless's called the dispatcher looks
figures out the linearization of the inheritance tree of the target object
of the method call, and then, one-at-a-time, goes over the objects in the
linearization, looking for an object whose METHODS hash contains an entry
for the name of the method. ("Linearization" meaning simply a list of
objects, in the order in which they should be searched.)

   Each call also creates an object, called a "callstate" object, one of
whose attributes is called "no_fail" (note lowercase), and whose value
starts out being undef.  If the dispatcher, while going thru the
linearization and looking at the METHODS, sees an object with a defined
'NO_FAIL' attribute (note uppercase), it uses that value (the value of the
first object in the list with a defined NO_FAIL attribute) to set the
no_fail attribute of the callstate.  If it finishes searching the list and
hasn't seen an object with a METHODS entry for the method it's dispatching
for, one of two things will happen: if no_fail is set to true, the
dispatcher will act as if it found the method and its value was
sub{return}.  Otherwise, the dispatcher will die with a fatal error like:

     Can't find method foo in OBJECT_NAME or any ancestors

   So, normally, the only way for the no_fail attribute of the callstate
to be usefully set is for the dispatcher to have seen an object with a
NO_FAIL attribute set.  In other words, if you want method lookup in an
object to be unfailing, set $x->{'NO_FAIL'} = 1 for it or any of its
ancestors; and if you want to override *that* for a descendant, set its
$y->{'NO_FAIL'} = 0.  (Note that just for sake of sanity, the NO_FAIL of
$ROOT is set to 0.)

   But in the case of using callstate->NEXT call to continue a method
dispatch (i.e., getting the dispatcher to pick up where it left off), you
may want to control the callstate's no_fail attribute directly, regardless
of the NO_FAIL attributes of any of the objects the dispatcher's seen so
far.  In that case, you can use the $callstate->set_no_fail_true to set
no_fail to true (i.e., lookup failures from NEXTing off of this callstate
don't generate fatal errors).  See the section on callstates, below, for
more options.

CALLSTATES
==========

   Every time you call a method on a Class::Classless object (whether
normally, or via a $callstate->NEXT(...) call), a new
Class::Classless::CALLSTATE object is created, and passed as $_[1] to that
method.  Besides this being the way I happen to implement
$callstate->NEXT(*methodname*, *arguments*) (by recording the state of the
dispatcher for later resumption), you can use this object to get
metainformation about this method call.  You can access that information
like so:

   * $callstate->target - the object that was the target of the method
call.  Same as the $_[0] that the method sees.

   * $callstate->found_name - the name this method was called as.

   * $callstate->lineage - the list of objects representing the
linearization of the target object's ISA tree.  (Same as $obj->ISA_TREE.)

   * $callstate->home - the object the called method was found in.

   * $callstate->sub_found - the routine that is being called.  Same as
$callstate->home->{'METHODS'}{$callstate->target}.

   * $callstate->found_depth - the number representing the index in the
$callstate->lineage list where this method was found.  In other words,
$callstate->home is ($callstate->lineage)[$callstate->found_depth].

   * $callstate->set_no_fail_true - set the no_fail attribute of this
callstate to true - meaning failure is impossible for any NEXT calls based
on this call.  (Obviously it's meaningless to consider failure of the
current method - it was already found, otherwise how could there be code
that's accessing its callstate!)  I expect this is useful for cases where
you want to NEXT, but aren't sure that there is a next method in the tree.
With the no_fail set, failure in the NEXT lookup will act as if it
triggered a method consisting of just sub { return; }.

   * $callstate->set_no_fail_false - set the no_fail attribute of this
callstate to true - meaning failure is possible for any NEXT calls in the
contituation of the current call state.  I don't anticipate this being
useful, but I provide it for completeness.

   * $callstate->set_no_fail_undef - set the no_fail attribute of this
callstate to undef - meaning that failure is possible, but that this value
can be set by the next object in the linearization of the inheritance
tree.  I don't anticipate this being useful, but I provide it for
completeness.

   * $callstate->no_fail - returns the value of no_fail attribute of this
callstate so far.  See the section "The NO_FAIL attribute", above.  I
don't anticipate this being useful, but I provide it for completeness.

   * $callstate->via_next - return true the current method was called via
$callstate->NEXT.  Otherwise returns false.

   The whole callstate mechanism (used by the above methods as well as by
the NEXT method) assumes you don't change the object's ISA tree (or any of
the METHODS hashes in any part of the ISA tree) in the middle of the call.
If you do, the information in $callstate will be out of synch with
reality (since it contains the linearization as of the *beginning* of the
call)), which is fine as long as you don't use it for anything (like
NEXTing) after that point, in that call.

MORE ON NEXT
============

   Calling $callstate->NEXT is the mechanism I allow for doing what Perl's
built-in object system does with SUPER:: calls, and like what some object
systems do with "before- and after-demons".

   The basic syntax to NEXT is as follows:

     $callstate->NEXT( method_name , ...arguments... );

   However, if you call it with a method_name of undef, it will use the
current value of $callstate->found_name, i.e., the name the currently
running method was found as.  Note that this can come to de undefined in
two ways - either by the parameter list being null, as in either of:

     $callstate->NEXT;
      ...AKA...
     $callstate->NEXT();

   or by being explicitly undef:

     $callstate->NEXT(undef, $foo, $bar);

   In either case, the undef is interpreted as $callstate->found_name.  I
offer this as just a (hopefully) convenient shortcut.

   Now, if you call NEXT and there is no method with the desired name in
the remainder of the linearization of the inheritance tree, what happens
depends on the no_fail attribute; if you want to insure that the NEXT will
not fail (since failing would mean a fatal error), you can set the
callstate's no_fail attribute to true:

     $callstate->set_no_fail_true

   (which means it can't fail.)

   Note, by the way, that NEXTing never automatically copies the argument
list of the current method for the next one. You have to do that yourself.
There's many ways to do it, but consider something like:

     $x->{"METHODS"}{"foo"} = sub {
       my($o, $cs) = splice(@_,0,2);
       # then copy arguments from @_, but don't change @_ any further:
       my($zaz, @foo) = @_
     
       ...stuff...
     
       # then you can pass on the arguments still in @_
       $cs->NEXT(undef,@_);
         # undef to mean 'the name I was called as'
     
       ...stuff...
     
     };

   If you forgot and just said $cs->NEXT() or (pointlessly)
$cs->NEXT(undef), then the next 'foo' method would have nothing in its
argument list after its usual two first items (the target object and the
callstate).

   A further note: currently, each method call (whether normal, or via a
NEXT) creates a new callstate object.  However, when NEXTing, the
attributes of the current callstate object are copied into the new
callstate object - except for the via_next attribute, which is forced to
true, of course.

BASIC IMPLEMENTATION STRATEGY
=============================

   This module does what it does by blessing all "Class::Classless"
objects into a class (Class::Classless::X, in point of fact) that provides
no methods except for an AUTOLOAD method that intercepts all method calls
and does the dispatching.  This is how I fiendishly usurp Perl's normal
method dispatching scheme.  (Actually I do provide other methods upfront:
can, VERSION, isa, DESTROY, and `ISA_TREE', as I basically have to, it
turns out.)

   Consult the source for details.  It's not that long.

CAVEATS AND MUSINGS
===================

   * The moral of this module is that if you don't like the object
framework that comes with a language, quit your bitching and just make
your own!  And the meta-moral is that object systems aren't black boxes
that have to be fused with the language itself.

   * Note that the can you may export from UNIVERSAL has nothing at all to
do with the can that you should be using for Class::Classless objects.
The only way you should call can on classless objects is like
$obj->can('foo').

   * How to test if something is a classless object: `ref($obj) eq
'Class::Classless::X''

   * Don't make cyclic trees.  I don't go to extreme lengths to stop you
from doing so, but don't expect sane behavior if you do.

   * The reason the $callstate->NEXT('foo') is called NEXT is because it
starts looking in the next object in the linearization of the ISA_TREE.
This next object is not necessarily an ancestor (i.e., a *super*ior
object) of the current object - in the above section, X is A's next node,
altho A is clearly not a superior node.

   * Don't try to derive new classes from any of the classes that
Class::Classless defines.  First off, it may not work, for any reading of
"work".  Second off, what's the point?

   * Note that there's currently no mechanism for parent objects to know
what their children are.  However, if you needed this, you could override
the clone method with something that would track this.  But note that this
would create circular data structures, complicating garbage collection -
you'd have to explicitly destroy objects, the way you have to with
Tree::DAG_Node nodes.

   * Why don't I let objects define their own DESTROY methods?  One short
reason: this unpredictably and intermittently triggers a strange bug in
Perl's garbage collection system during global destruction.  Better,
longer reason: I don't see any way to make sure that, during global
destruction, Perl never destroys a parent before its children.  If a
parent is destroyed before its children, and that parent provides a
DESTROY that the children inherit, then when it comes time for the
children to be destroyed, the DESTROY method they planned on using would
have become inaccessible.  This seems an intractable problem.

   * Callstate objects were added as an afterthought.  They are meant to
be small and inexpensive, not extensible.  I can't imagine a use for them
other than the uses outlined in the documentation - i.e., getting at (or
sometimes modifying) an attribute of the current state of the method
dispatcher. If you're considering any other use of callstate objects,
email me - I'd be interested in hearing what you have in mind.

   * While I was writing Class::Classless, I read up on Self.  To quote
FOLDOC (`http://foldoc.doc.ic.ac.uk/foldoc/foldoc.cgi?query=Self'), Self
is/was "a small, dynamically typed object-oriented language, based purely
on prototypes and delegation. Self was developed by the Self Group at Sun
Microsystems Laboratories, Inc. and Stanford University. It is an
experimental exploratory programming language."  For more information, see
`http://www.sunlabs.com/research/self/'

YOU KNOW WHAT THEY SAY...
=========================

   To Marx, a classless society never meant the absolute equality of
result, but merely the absence of artificial barriers between social
groups. According to David McClellan, a Marx scholar, Marx "had a dynamic
or subjective element in his definition of class; a class only existed
when it was conscious of itself as such, and this always implied common
hostility to another social group." In *The Thought of Karl Marx*, (New
York: Harper & Row, 1971) p. 155.

   - `http://www.polyconomics.com/searchbase/kmnotes.htm'

   The thanks for the quote as well as for thinking of the name
"Class::Classless" go to Veblen, who can be seen making that secret potato
soup of his at `http://www.llnl.gov/llnl/art-cv/image1.jpg'

   Thanks to my many minions in EFNet #perl for help, suggestions, and
encouragement.  Especial thanks to Merlyn, Halfjack, and Skrewtape for
assuring me that the idea of objects-without-class wasn't just some
Felliniesque fever dream I had, but is a concept that has precedent in
other programming languages.

   And thanks to Damian Conway for stritching the brines of his poor
students with this module.

SEE ALSO
========

   For information on Perl's classy OOP system, see *Note Perlobj:
(perl.info)perlobj,, *Note Perltoot: (perl.info)perltoot,, *Note
UNIVERSAL: UNIVERSAL,, and Damian Conway's excellent book *Object Oriented
Perl* from Manning Press.

COPYRIGHT
=========

   Copyright (c) 1999, 2000 Sean M. Burke.  All rights reserved.

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

AUTHOR
======

   Sean M. Burke, sburke@cpan.org


