=head1 NAME

Class::Generate - Generate Perl class hierarchies

=head1 SYNOPSIS

 use Class::Generate qw(&class &subclass);

 # Declare class Class_Name, with the following types of members:
 class
     Class_Name => [
         s => '$',			# scalar
	 a => '@',			# array
	 h => '%',			# hash
	 c => 'Class',			# Class
	 c_a => '@Class',		# array of Class
	 c_h => '%Class',		# hash of Class
         '&m' => 'body',		# method
     ];

 # Allocate an instance of class_name, with members initialized to the
 # given values (pass arrays and hashes using references).
 $obj = Class_Name->new ( s => scalar,
			  a => [ values ],
			  h => { key1 => v1, ... },
			  c => Class->new,
			  c_a => [ Class->new, ... ],
			  c_h => [ key1 => Class->new, ... ] );

		# Scalar type accessor:
 $obj->s($value);			# Assign $value to member s.
 $member_value = $obj->s;		# Access member's value.

		# (Class) Array type accessor:
 $obj->a([value1, value2, ...]);	# Assign whole array to member.
 $obj->a(2, $value);			# Assign $value to array member 2.
 $obj->add_a($value);			# Append $value to end of array.
 @a = $obj->a;				# Access whole array.
 $ary_member_value = $obj->a(2);	# Access array member 2.
 $s = $obj->a_size;			# Return size of array.

		# (Class) Hash type accessor:
 $obj->h({ k_1=>v1, ..., k_n=>v_n })	# Assign whole hash to member.
 $obj->h($key, $value);			# Assign $value to hash member $key.
 %hash = $obj->h;			# Access whole hash.
 $hash_member_value = $obj->h($key);	# Access hash member value $key.
 @keys = $obj->h_keys;			# Access keys of member h.
 @values = $obj->h_values;		# Access values of member h.

 subclass s  => [ <more members> ], parent => 'class_name';

=head1 DESCRIPTION

The C<Class::Generate> package exports functions that take as arguments
a class specification and create from these specifications a Perl 5 class.
The specification language allows many object-oriented constructs:
typed members, inheritance, private members, required members,
default values, object methods, class methods, class variables, and more.

CPAN contains similar packages.
Why another?
Because object-oriented programming,
especially in a dynamic language like Perl,
is a complicated endeavor.
I wanted a package that would work very hard to catch the errors you
(well, I anyway) commonly make.
I wanted a package that could help me
enforce the contract of object-oriented programming.
I also wanted it to get out of my way when I asked.

=head1 THE CLASS FUNCTION

You create classes by invoking the C<class> function.
The C<class> function has two forms:

    class Class_Name => [ specification ];	# Objects are array-based.
    class Class_Name => { specification };	# Objects are hash-based.

The result is a Perl 5 class, in a package C<Class_Name>.
This package must not exist when C<class> is invoked.

An array-based object is faster and smaller.
A hash-based object is more flexible.
Subsequent sections explain where and why flexibility matters.

The specification consists of zero or more name/value pairs.
Each pair declares one member of the class,
with the given name, and with attributes specified by the given value.

=head1 MEMBER TYPES

In the simplest name/value form,
the value you give is a string that defines the member's type.
A C<'$'> denotes a scalar member type.
A C<'@'> denotes an array type.
A C<'%'> denotes a hash type.
Thus:

    class Person => [ name => '$', age => '$' ];

creates a class named C<Person> with two scalar members,
C<name> and C<age>.

If the type is followed by a class name,
the member is restricted to a blessed reference of the class
(or one of its subclasses),
an array whose elements are blessed references of the class,
or a hash whose keys are strings
and whose values are blessed references of the class.
For scalars, the C<$> may be omitted;
i.e., C<Class_Name> and C<$Class_Name> are equivalent.
The class need not be declared using the C<Class::Generate> package.

=head1 CREATING INSTANCES

Each class that you generate has a constructor named C<new>.
Invoking the constructor creates an instance of the class.
You may provide C<new> with parameters to set the values of members:

    class Person => [ name => '$', age => '$' ];
    $p = Person->new;			# Neither name and age are defined.
    $q = Person->new( name => 'Jim' );	# Only name is defined.
    $r = Person->new( age => 32 );	# Only age is defined.

=head1 ACCESSOR METHODS

A class has a standard set of accessor methods for each member you specify.
The accessor methods depend on a member's type.

=head2 Scalar (name => '$', name => 'Class_Name', or name => '$Class_Name')

The member is a scalar.
The member has a single method C<name>.
If called with no arguments, it returns the member's current value.
If called with arguments, it sets the member to the first value:

    $p = Person->new;
    $p->age(32);		# Sets age member to 32.
    print $p->age;		# Prints 32.

If the C<Class_Name> form is used, the member must be a reference blessed
to the named class or to one of its subclasses.
If Perl's C<-w> flag is used,
the method will C<croak> if the argument is not a blessed reference
to an instance of C<Class_Name> or one of its subclasses.

    class Person => [
	name => '$',
	spouse => 'Person'	# Works, even though Person
    ];				# isn't yet defined.
    $p = Person->new(name => 'Simon Bar-Sinister');
    $q = Person->new(name => 'Polly Purebred');
    $r = Person->new(name => 'Underdog');
    $r->spouse($q);				# Underdog marries Polly.
    print $r->spouse->name;			# Prints 'Polly Purebred'.
    print "He's married" if defined $p->spouse;	# Prints nothing.
    $p->spouse('Natasha Fatale');		# Croaks.

=head2 Array (name => '@' or name => '@Class')

The member is an array.
If the C<@Class> form is used, all members of the array must be a blessed reference
to C<Class> or one of its subclasses.
An array member has three associated methods:

=over 4

=item C<name>

With no argument, C<name> returns the member's whole array.

With one argument, C<name>'s behavior depends on
whether the argument is an array reference.
If it is not, then the argument must be an integer I<i>,
and C<name> returns element I<i> of the member.
If no such element exists, C<name> returns C<undef>.
If the argument is an array reference,
it is cast into an array and assigned to the member.

With two arguments, the first argument must be an integer I<i>.
The second argument is assigned to element I<i> of the member.

=item C<add_name>

This method appends its arguments to the member's array.

=item C<name_size>

This method returns the index of the last element in the array.

=back

For example:

    class Person => [ name => '$', kids => '@Person' ];
    $p = Person->new;
    $p->add_kids(Person->new(name => 'Heckle'),
		 Person->new(name => 'Jeckle'));
    print $p->kids_size;	# Prints 1.
    $p->kids([Person->new(name => 'Bugs Bunny'),
	      Person->new(name => 'Daffy Duck')]);
    $p->add_kids(Person->new(name => 'Yosemite Sam'),
		 Person->new(name => 'Porky Pig'));
    print $p->kids_size;	# Prints 3.
    $p->kids(2, Person->new(name => 'Elmer Fudd'));
    print $p->kids(2)->name;	# Prints 'Elmer Fudd'.
    @kids = $p->kids;		# Get all the kids.

=head2 Hash (name => '%' or name => '%Class')

The member is a hash.
If the C<%Class> form is used, all values in the hash
must be a blessed reference to C<Class> or one of its subclasses.
A hash member has three associated methods:

=over 4

=item C<name>

With no arguments, C<name> returns the member's whole hash.

With one argument that is a hash reference,
the member's value becomes the argument.
With one argument that is a string,
the element of the hash keyed by that string is returned.
If no such element exists, C<name> returns C<undef>.

With two arguments, the second argument is assigned to the hash,
keyed by the string representation of the first argument.

=item C<name_keys>

The C<name_keys> method returns all keys associated with the member.

=item C<name_values>

The C<name_values> method returns all values associated with the member.

=back

For example:

    class Person => [ name => '$', kids => '%Kid_Info' ];
    class Kid_Info => [
	grade  => '$',
	skills => '@'
    ];
    $f = new Person(
	name => 'Fred Flintstone',
	kids => { Pebbles => new Kid_Info(grade => 1,
				          skills => ['Programs VCR']) }
    );
    print $f->kids('Pebbles')->grade;	# Prints 1.
    $b = new Kid_Info;
    $b->grade('Kindergarten');
    $b->skills(['Knows Perl', 'Phreaks']);
    $f->kids('BamBam', $b);
    print join ', ', $f->kids_keys;	# Prints "Pebbles, BamBam",
					# though maybe not in that order.

=head1 COMMON METHODS

All members also have a method C<undef_name>.
This method undefines an member.

=head1 ADVANCED MEMBER SPECIFICATIONS

As shown, you specify each member as a C<name=E<gt>value> pair.
If the C<value> is a string, it specifies the member's type.
The value may also be a hash reference.
You use hash references to specify additional member attributes.
The following is a complete list of the attributes you may specify for an member:

=over 4

=item type=>string

If you use a hash reference for a member's value,
you I<must> use the C<type> attribute to specify its type:

    scalar_member => { type => '$' }

=item required=>boolean

If the C<required> attribute is true,
the member must be passed each time the class' constructor is invoked:

    class Person => [ name => { type => '$', required => 1 } ];
    Person->new ( name => 'Wilma' );	# Valid
    Person->new;			# Invalid

Also, you may not call C<undef_name> for the member.

=item default=>value

The C<default> attribute provides a default value for a member
if none is passed to the constructor:

    class Person => [ name => '$',
		      job => { type => '$',
			       default => "'Perl programmer'" } ];
    $p = Person->new(name => 'Larry');
    print $p->job;		# Prints 'Perl programmer'.
    $q = Person->new(name => 'Bjourne', job => 'C++ programmer');
    print $q->job;		# Unprintable.

The value is treated as a string that is evaluated
when the constructor is invoked.

For array members, use a string that looks like a Perl expression
that evaluates to an array reference:

    class Person => { name => '$',
		      lucky_numbers => { type => '@',
					 default => '[42, 17]' } };
    class Silly => {
	 UIDs => {
	     type => '@',
	     default => 'do { local $/ = undef;
			      open PASSWD, "/etc/passwd";
			      [ map $$_[2], split /\n/, <PASSWD> ] }' } };

Specify hash members analogously.

Because the value is evaluated each time the constructor is invoked,
it may change between invocations.
If the value is a reference rather than a string,
it is not re-evaluated.
In the following, default values for C<e1> and C<e2>
are based on the members of C<@default_value> each time C<Example-E<gt>new> is invoked,
whereas C<e3>'s default value is set when the C<class> function is invoked
to define C<Example>:

    @default_value = (1, 2, 3);
    $var_name = '@' . __PACKAGE__ . '::default_value';
    class Example => {
        e1 => { type => '@', default => "[$var_name]" },
	e2 => { type => '@', default => \@default_value },	
	e3 => { type => '@', default => [ @default_value ] }
    };
    Example->new;	# e1, e2, and e3 are all identical.
    @default_value = (10, 20, 30);
    Example->new;	# Now only e3 is (1, 2, 3).

If the default value is a string,
the C<class> function evaluates it to ensure that it
is of the correct type for the member.
Be aware of this if your default value has side effects.

=item post=>code

The value of this attribute is a string of Perl code.
It is executed immediately after the member's value is modified through an accessor.
Within C<post> code, you can refer to members as if they were regular Perl identifiers.
For instance:

    class Person => [ age => { type => '$',
			       post => '$age *= 2;' } ];
    $p = Person->new(age => 30);
    print $p->age;	# Prints 30.
    $p->age(15);
    print $p->age;	# Prints 30 again.

You reference array and hash members as usual.
You can reference individual elements, or the whole list:

    class Foo => [
	m1 => { type => '@', post => '$m1[$#m1/2] = $m2{xxx};' },
	m2 => { type => '%', post => '@m1 = keys %m2;' }
    ];

You can also invoke accessors by prefixing them with a C<&>:

    class Bar => [ 
	m1 => { type => '@', post => '&undef_m1;' },
	m2 => { type => '%', post => '@m1 = &m2_keys;' }
    ];

=item pre=>code

The C<pre> key is similar to the C<post> key,
but it is executed just before an member is changed.
It is I<not> executed if the member is only accessed.
Any variables that you declare in it are guaranteed accessible
to the C<post> code.

=item assert=>expression

The value of this key should be a Perl expression
that evaluates to true or false.
Use member names in the expression, as with C<post>.
The expression will be tested any time
the member is modified through its accessors.
Your code will C<croak> if the expression evaluates to false.
For instance, 

    class Person => [
	name => '$',
	age => { type => '$',
		 assert => '$age =~ /^\d+$/ && $age < 200' } ];

ensures the age is reasonable.

The assertion is executed after any C<post> code associated with the member.

=item private=>boolean

If the C<private> attribute is true,
the member cannot be accessed outside the class;
that is, it has no accessor functions that can be called
outside the scope of the package defined by C<class>.
A private member can, however, be accessed in C<post>, C<pre>, and C<assert>
code as if it were a non-private member.

=item readonly=>boolean

If this attribute is true, then the member cannot be modified
through its accessors.
Users can set the member only by using the class constructor.
The member's accessor that is its name can retrieve but not set the member.
The C<undef_>I<name> accessor is not defined for the member,
nor are other accessors that might modify the member.
(Code in C<post> can set it, however.)

=back

=head1 AFFECTING THE CONSTRUCTOR

You may include a C<new> attribute in the specification to affect the constructor.
Its value must be a hash reference.
Its attributes are:

=over 4

=item required=>list of constraints

This is another (and more general) way to require that parameters be passed to the constructor.
Its value is a reference to an array of constraints.
Each constraint is a string that must be an expression
composed of Perl logical operators and member names.
For example:

    class Person => {
	name   => '$',
        age    => '$',
	height => '$',
	weight => '$',
	new => { required => ['name', 'height^weight'] }
    };

requires member C<name>, and exactly one of C<height> or C<weight>.
Note that the names are I<not> prefixed with C<$>, C<@>, or C<%>.

Specifying a list of constraints as an array reference can be clunky.
The C<class> function also lets you specify the list as a string,
with individual constraints separated by spaces.
The following two strings are equivalent to the above C<required> attribute:

    'name height^weight'
    'name&(height^weight)'

However, C<'name & (height ^ weight)'> would not work.
The C<class> function interprets it as a five-member list,
four members of which are not valid expressions.

This equivalence between a reference to array of strings
and a string of space-separated items is used throughout C<Class::Generate>.
Use whichever form works best for you.

=item post=>string of code

The C<post> key is similar to the C<post> key for members.
Its value is code that is inserted into the constructor
after parameter values have been assigned to members.
The C<class> function performs variable substitution.

The C<pre> member is I<not> recognized in C<new>.

=item assert=>expression

The C<assert> key's value is inserted
just after the C<post> key's value (if any).
Assertions for members are inserted after the constructor's assertion.

=item comment=>string

This attribute's value can be any string.
If you save the class to a file
(see L</Saving the Classes>),
the string is included as a comment just before
the member's methods.

=item style=>style definition

The C<style> attribute controls how parameters are passed to the class' constructor.
See L<PARAMETER PASSING STYLES>.

=back

=head1 ADDING METHODS

Accessors often do not provide a class with enough functionality.
They also do not encapsulate algorithms.
For these reasons, the C<class> function lets you add methods.
Both object methods and class methods are allowed.

Add methods using an member of the form C<'&name'=E<gt>body>,
where C<body> is a string containing valid Perl code.
This yields a method C<name> with the specified C<body>.
For object methods, the C<class> function performs variable substitution as described above.
For example,

    class Person => [ first_name => '$',
		      last_name  => '$',
		      '&name'    => 'return "$first_name $last_name";'
    ];
    $p = Person->new(first_name => 'Barney', last_name => 'Rubble');
    print $p->name;	# Prints "Barney Rubble".

A method has the following attributes which,
like members, are specified as a hash reference:

=over 4

=item body=>code

This attribute specifies the method's body.
It is required if other attributes are given.

=item private=>boolean

The method cannot be accessed outside the class.

    class Example => [
	m1 => '$',
	m2 => '$',
	'&public_interface' => 'return &internal_algorithm;',
	'&internal_algorithm' => { private => 1,
				   body => 'return $m1 + 4*$m2;' }
    ];
    $e = Example->new(m1 => 2, m2 => 4);
    print $e->public_interface;		# Prints 18.
    print $e->internal_algorithm;	# Run-time error.

=item class_method=>boolean

If true, the method applies to classes rather than objects.
Member name substitution is I<not> performed within a class method.
You can, however, use accessors, as usual:

    class Foo => [
	m1 => '$', m2 => '@',
	'&copy' => { class_method => 1,
		     body => 'my $in = $_[0];
			      my $out = Foo->new(m1 => $in->m1,
						 m2 => [$in->m2]);
			      return $out;' }
    ];
    $f1 = Foo->new;
    $f2 = Foo->copy($f1);

=item objects=>list of object instance expressions

This attribute is only used for class methods.
It is needed when the method refers to a private member or method.
Its argument is a list,
each element of which is a Perl expression that occurs in the body
of the class method.
The expression must evaluate to an instance of the class.
It will be replaced by an appropriate reference to the private member or method.
For example:

    class Bar => [
	mem1 => '$',
	mem2 => { type => '@', private => 1 },
	'&meth1' => 'return $mem1 + $#mem2;',
	'&meth2' => { private => 1,
		      body    => 'return eval join "+", @mem2;' },
	'&cm1' => { class_method => 1,
		    objects => '$o',
		    body => 'my $o = Bar->new(m1 => 8);
			     $o->mem2([4, 5, 6]);
			     return $o->meth2;' },
	'&cm2' => { class_method => 1,
		    objects => ['$o', 'Bar->new(m1 => 3)'],
		    body => 'my $o => Bar->new(m1 => 8);
			     $o->mem2(0, Bar->new(m1 => 3)->meth2);
			     return $o;' }
    ];

The C<objects> attribute for C<cm1> tells C<class>
to treat all occurrences of the string C<$o> as an instance of class C<Bar>,
giving the expression access to private members and methods of C<Bar>.
The string can be an arbitrary expression, as long as it's valid Perl
and evaluates to an instance of the class;
hence the use of C<Bar-E<gt>new(m1 =E<gt> 3)> in C<cm2>.
The string must match exactly,
so C<Bar-E<gt>new(m1 =E<gt> 8)> is not replaced.

=back

=head1 THE SUBCLASS FUNCTION

The C<subclass()> function declares classes
that are subclasses of another class.
The statement:

    subclass S => [ specification ], parent => P

declares a package C<s>, and a constructor function C<new>, just like C<class>;
but C<s-E<gt>new> yields a blessed reference that inherits from C<p>.
You can use all the attributes discussed above in the specification
of a subclass.

Class C<p> need not have been defined
using the C<class> or C<subclass> function.
It must have a constructor named C<new>, however.

A subclass may be either an array or hash reference.
Its parent must be the same type of reference.

You can inherit from multiple classes, providing all are hash-based
(C<Class::Generate> does not support multiple inheritance
for array-based classes).
Just list more than one class as the value of C<parent>:

    subclass S => { specification }, parent => 'P1 P2 P3';

Elements of the C<@ISA> array for package C<S>
appear in the order you list them.
This guarantee should let you determine the order in which methods are invoked.

The subclass constructor automatically calls its parent constructor.
It passes to the parent constructor any parameters
that aren't members of the subclass.

Subclass members with the same name as that of their parent
override their parent methods.
If you want to access a parent member
within C<pre>, C<post>, or C<assertion> code,
you can do so by invoking C<$self-E<gt>SUPER::member>.
You cannot access private members.

=head1 FLAGS

You can affect the specification of a class using certain flags.
A flag is a key/value pair passed as an argument to C<class> (or C<subclass>).
The first character of the key is always a hyphen ("-").
The following is a list of recognized flags:

=over 4

=item -use=>list

Your C<pre> or C<post> code may want to use functions
declared in other packages.
List these packages as the value of the C<-use> flag.
For example, suppose you are creating a class that does date handling,
and you want to use functions in the C<Time::Local>
and C<Time::localtime> packages.
Write the class as follows:

    class Date_User => [ ... ],
	'-use' => 'Time::Local Time::localtime';

Any C<pre> or C<post> code can now access the
time functions declared in these two packages.

To import functions, you need to use the array reference form:

    class Foo => [ ... ],
	'-use' => ["FileHandle 'autoflush'"];

Otherwise, the C<class> function would assume you want to use two packages,
C<Filehandle> and C<'autoflush'>.

Package C<Carp> is automatically used if $WARNING is true.

=item -class_vars=>list

A class can have class variables,
i.e., variables accessible to all instances of the class
as well as to class methods.
Specify class variables using the C<-class_vars> flag.
For example, suppose you want the average age of all Persons:

    $compute_average_age = '$n++; $total += $age; $average = $total/$n;';
    class Person => [
	name => '$',
	age  => { type => '$', required => 1, readonly => 1 },
	new  => { post => $compute_average_age }
    ],
        '-class_vars' => '$n $total $average';
    $p = Person->new(age => 24);		# Average age is now 24.
    $q = Person->new(age => 30);		# Average age is now 27.

You can also provide an initial value for class variables.
Specify the value of C<-class_vars> as an array reference.
If any member of this array is a hash reference,
its members are taken to be variable name/initial value pairs.
For example:

    class Person => [ name => '$',
		      age => { type => '$', required => 1, readonly => 1 },
		      new => { post => $compute_average_age }
    ],
	  '-class_vars' => [ { '$n' => 0 },
			     { '$total' => 0 },
			     '$average' ];

=item -virtual=>boolean

Virtual classes are a useful modeling aid and debugging tool.
Specify them using the C<-virtual> flag:

    class Parent => [ e => '$' ], '-virtual' => 1;
    subclass Child => [ d => '$' ], parent => 'Parent';
    Child->new;		# This is okay
    Parent->new;	# This croaks.

There is no built-in way to specify a virtual method,
but the following achieves the desired effect:

    class Foo => [ '&m' => 'die "m is a virtual method";' ];

=item -comment=>string

The string serves as a comment for the class.

=item -options=>{ options }

This flag lets you specify options that alter your class' behavior.
See L</OPTIONS>.

=back

=head1 PARAMETER PASSING STYLES

By default, parameters to the constructor are passed
using a C<name=E<gt>value> form.
You have some control over this using the C<style> key
in a constructor's C<new> specifier.
It lets you pass parameters to constructors using one of the following styles:

=over 4

=item Key/Value

This is the default.
Parameters are passed using the C<name=E<gt>value> form,
as shown in previous examples.
Specify it as C<style=E<gt>'key_value'> if you want to be explicit.

=item Positional

Parameters are passed based on a positional order you specify.
For example:

    class Foo => [ e1 => '$', e2 => '@', e3 => '%',
	           new => { style => 'positional e1 e2 e3' } ];
    $obj = Foo->new(1);			# Sets e1 to 1.
    $obj = Foo->new(1, [2,3]);		# Ditto, and sets e2 to (2,3).
    my %hash = (foo => 'bar');
    $obj = Foo->new(1,			# Ditto,
		    [2, 3],		# ditto,
		    {%hash});		# and sets e3 to %hash.

You must list all non-private members,
although you do not have to include all of them in
every invocation of C<new>.
Also, if you want to set C<e1> and C<e3> but not C<e2>,
you can give C<undef> as C<e2>'s value:

    $obj = Foo->new(1, undef, { e3_value => 'see what I mean?' });

=item Mixed Styles

Parameters are passed mixing the positional and key/value styles.
The values following C<mix> are the names of the positional parameters,
in the order in which they will be passed.
This style is useful when certain parameters are "obvious".
For example:

    class Person => [
	first_name => { type => '$', required => 1 },
	last_name  => { type => '$', required => 1 },
	favorite_language => '$',
	favorite_os	  => '$',
	new => { style => 'mix first_name last_name' }
    ];
    $obj = Person->new('Joe',  'Programmer', favorite_language => 'Perl');
    $obj = Person->new('Sally', 'Codesmith', favorite_os       => 'Linux');

The positional parameters need not be required,
but they must all be given if you want to set any members passed as
key/value parameters.

=item Your Own Parameter Handling

Finally, sometimes you want a constructor whose parameters aren't the members.
Specify such classes using C<own>.
Access the parameters through C<@_>, as usual in Perl:

    class Person => [
	first => { type => '$', private => 1 },
	last  => { type => '$', private => 1 },
	new   => { style => 'own',
		   post => '($first, $last) = split /\s+/, $_[0];' },
	'&name' => q|return $last . ', ' . $first;|
    ];
    $p = Person->new('Fred Flintstone');
    print $p->name;			# Prints 'Flintstone, Fred'.

If C<own> is followed by a space, and the class has a parent,
everything after the space is treated as
a space-separated list of Perl expressions.
The expressions are passed to the superclass constructor in the order given.
Thus:

    subclass Child => [
	grade => '$',
	new   => { style => 'own $_[0]', post => '$grade = $_[1];' }
    ], parent => 'Person';

Now you can create a C<Child> by passing the grade as the second parameter,
and the name as the first:

    $c = Child->new('Penny Robinson', 5);

=back

The C<subclass> function has some understanding of superclass parameter forms.
Unfortunately, not all combinations make sense.
You will get a warning if you do something illogical.
The key/value style is safest.

=head1 OPTIONS

The C<Class::Generate> package provides what its author believes is
reasonable default style and behavior.
But if you disagree,
there are certain defaults you can control on a class-by-class basis,
or for all classes you generate.
These defaults are specified as options.
An option is given in one of two ways:

=over 4

=item 1.

Via the C<-options> flag,
the value of which is a hash reference containing the individual options.
This affects an individual class.

=item 2.

By setting a variable declared in C<Class::Generate>.
The variable has the same name as the option.
This affects all subsequently generated classes
except those where the option is explicitly overridden
via the C<-options> flag.
You may export these variables, although they are not exported by default.

=back

The following sections list the options
that C<class> and C<subclass> recognize.

=head2 Saving the Classes

If the C<save> option is true for class C<c>,
the code implementing it will be saved to file C<c.pm>.
This is useful in several situations:

=over 4

=item 1.

You may need functionality that C<class> and C<subclass> cannot provide.

=item 2.

Errors in your methods, or in C<pre> and C<post> code,
can result in obscure diagnostics.
Debugging classes is easier if they are saved in files.
This is especially true if you use Emacs for debugging,
as Emacs does not handle evaluated expressions very well.

=item 3.

If you have many classes,
there is overhead in regenerating them each time you execute your program.
Accessing them in files may be faster.

=back

If the value of C<save> looks like a Perl file name
(i.e., if it ends in C<.pl> or C<.pm>),
the class is appended to that file.
This feature lets your program avoid the overhead
of opening and closing multiple files.
It also saves you from the burden of maintaining multiple files.

All comments specified using C<comment> attributes
and the C<-comment> flag are saved along with your code.

=head2 Passing References

Sometimes you want to be able to assign a whole array to an array member
(or a whole hash to a hash member):

    class Person => [
	name	=> '$',
	parents => '@Person',
	new	=> { style => 'positional name parents' }
    ];
    $p = Person->new('Will Robinson');
    $p->parents( [ Person->new('John Robinson'),
		   Person->new('Maureen Robinson') ] );

But sometimes you don't.
Often you only have one member value available at any time,
and you only want to add values:

    class Person => [
	name	=> '$',
	parents => '@Person',
	new	=> { style => 'positional name parents' }
    ],
	'-options' => { accept_refs => 0 };
    $p = Person->new('Will Robinson');
    $p->add_parents( Person->new('Maureen Robinson'),
		     Person->new('John Robinson') );

Passing references is a matter of taste and situation.
If you don't think you will need or want to do it,
set the C<accept_refs> option to false.
An added benefit is that the classes will catch more parameter-passing errors,
because with references there are two meanings
for passing a single parameter to the method.

=head2 Strictness

By default, the classes include a C<use strict> directive.
You can change this (if you must) using a false value for the C<strict> option.

=head2 Amending a Package

C<Class::Generate> is intended for generating classes,
not packages containing classes.
For that reason, C<class> and C<subclass> croak if you try to define
a class whose name is a package that already exists.
Setting the C<allow_redefine> option to true changes this behavior.
It also opens up a minefield potential errors, so be careful.

=head1 SANITY CHECKING

Several sections have mentioned errors that will cause your program to croak.
Actually this only happens if you use Perl's C<-w> flag.
Once your classes are I<fully> debugged,
you may want to stop using C<-w> for the sake of efficiency.
But go slow on that.

Assertions are included only if the C<-w> flag is used.

=head1 DIAGNOSTICS

The following is a list of the diagnostics the C<class> and C<subclass>
functions can produce.
Each diagnostic is prefixed with "(F)" or "(W)",
indicating that it is fatal or a warning, respectively.
Warning messages are only emitted if you use Perl's C<-w> flag.

Classes that contain user defined code can yield Perl errors and warnings.
These messages are prefixed by one of the following phrases:

    Class_Name: Member "name": In "<x>" code:
    Class_Name: Method "name":

where C<E<lt>xE<gt>> is one of C<pre>, C<post>, or C<assert>.
See L<perldiag> for an explanation of such messages.

=head2 Compile-Time Diagnostics

The C<class> and C<subclass> functions emit the following diagnostics:

=over 4

=item "-class_vars" flag must be string or array reference

(F) The value of the C<-use> flag must be a string
containing a space-separated list of class variables,
or a reference to an array of strings,
each of which specifies one or more class variables.

=item "-use" flag must be string or array reference

(F) The value of the C<-use> flag must be a string
containing a space-separated list of packages to use,
or a reference to an array of strings,
each of which is a package to use.

=item %s: "self" is reserved

(F) The name C<self> cannot be used as a member or method name.

=item %s: A package of this name already exists

(F) The name passed to C<class> or C<subclass> must not be
the name of an existing package,
unless the C<allow_redefine> option is true.

=item %s: An array reference based subclass must have exactly one parent

(F) Multiple inheritance is only permitted for class hierarchies
specified as hash references.

=item %s: Base type does not match that of "%s"

(F) If the class specified using C<subclass> is specified as an array reference,
its parent(s) must also be specified as array references.
If it is specified as a hash reference,
its parent(s) must be specified as hash references.

=item %s: Cannot append to "%s": %s

The C<save> option was true,
but a class definition cannot be appended to the named file for the
specified operating system-specific reason.

=item %s: Cannot save to "%s": %s

(F) The C<save> option was true,
but the class cannot be saved to the named file for the
specified operating system-specific reason.

=item %s: Cannot continue after errors

(F) The class specification includes user defined code
that is not valid Perl.

=item %s: Default value for "%s" is not correctly typed

(W) The value of the C<default> attribute
specified for the named member is either a reference
that is does not match the type required for the member,
or a string that, when evaluated, does not match the member's type.

=item %s: Elements must be in array or hash reference

(F) A class specification must be an array or hash reference.
Scalars, lists, and other references are not allowed.

=item %s: Error in new => { style => '... %s' }: %s is not a member

(F) A class' constructor specifies a style that requires listing members,
and includes a value that is not a member.

=item %s: Extra parameters in style specifier

(F) A class' constructor was specified to use the C<mix> style,
but more values were listed than exist non-private members.

=item %s: Invalid member/method name "%s"

(F) The names of members and methods must be valid Perl identifiers,
starting with a letter or underscore and containing
only letters, underscores, or digits.

=item %s: Invalid parameter-passing style (must be string or array reference)

(F) Within the C<new> attribute of a class,
the C<style> attribute's value  must be given as a string
or a reference to an array of strings.

=item %s: Invalid parameter-passing style type "%s"

(F) Within the C<new> attribute of a class,
the C<style> attribute's value must begin with one of
the words C<key_value>, C<mix>, C<positional>, or C<own>.

=item %s: Invalid specification for objects of "%s" (must be string or array reference)

(F) For the named class method,
the expressions to be recognized as objects must be passed
as a string or a reference to a list of strings.

=item %s: Invalid specification for required constructor parameters (must be string or array reference)

(F) Within the C<new> attribute of a class,
the C<required> attribute's value must be given as a string
or a reference to an array of strings.

=item %s: Invalid specification of member "%s" (must be string or hash reference with "type" key)

(F) A member's specification must be given as either
a string (describing its type)
or a hash reference (which must contain the C<type> key).

=item %s: Invalid specification of method "%s" (must be string or hash reference with "body" key)

(F) The value of a method name must be a string
(specifying the method's body)
or a hash reference, one of whose elements is keyed by C<body>.

=item %s: Member "%s": "%s" is not a valid type

(F) The type of a member must be C<$>, C<@>, C<%>,
one of these three types followed by an identifier,
or an identifier.

=item %s: Member "%s": Unknown attribute "%s"

(W) One of the attributes given in the hash reference specifying the named
member is not a recognized attribute.

=item %s: Method "%s": Unknown attribute "%s"

(W) One of the attributes given in the hash reference specifying the named
method is not a recognized attribute.

=item %s: Missing/extra members in style

(F) A class' constructor was specified to use the C<positional> style,
but not all non-private members (or too many members) were listed.

=item %s: Name "%s" used %d times

(F) The set of member and method names cannot contain duplicates.
Member and method names share the same namespace.

=item %s: Parent class "%s" was not defined using CLASS or SUBCLASS

(W) The C<subclass> function permits parents to be any package,
not just those defined using C<class> and C<subclass>.
However, because certain capabilities are lost (e.g., base type checking),
it emits warnings when it detects such subclasses.

=item %s: Parent package "%s" does not exist

(F) The C<subclass> function requires all parent classes
to exist (meaning each is a package) before it is invoked.

=item %s: Probable mismatch calling constructor in superclass "%s"

(W) The C<subclass> function's constructor specifies
a parameter passing style that is likely to conflict
with the style of its parent's.

=item %s: Required params list for constructor contains unknown member "%s"

(F) Within the C<new> attribute of a class,
the C<required> attribute's value contains a name that
is not given as class member.

=item %s: Specification for "new" must be hash reference

(F) The C<new> attribute of a class must be given as a hash reference.

=item Cannot save reference as initial value for "%s"

(W) References are legal default or initial values.
However, they cannot be saved using the C<save> option.

=item Each class variable must be scalar or hash reference

(F) The specification of a class variable must be either a string
containing a valid Perl variable name, or a hash reference;
for each key/value pair of the reference
the key must be a valid Perl variable name,
and the value must be a Perl expression
to be used as the variable's default value.

=item Expected string or array reference

(F) The value of an attribute's key/value pair should have been
a string or an array reference, but was not.

=item Expected string or hash reference

(F) The value of an attribute's key/value pair should have been
a string or an array reference, but was not.

=item Invalid parent specification (must be string or array reference)

(F) The C<subclass> function requires the class' parent(s) to be specified
as either a string, or a list of strings passed as an array reference.

=item Missing subclass parent

(F) The C<subclass> function requires the class' parent(s) to be specified,
using the C<parent=E<gt>list> form.

=item Missing/extra arguments to class()

(F) The C<class> function requires at least two arguments:
the class' name and specification.
Its other arguments must be flags.

=item Missing/extra arguments to subclass()

(F) The C<subclass> function requires at least four arguments:
the class' name, the class' specification,
and the class' parent as a key/value pair.
Other arguments to C<subclass> must be flags.

=item Options must be in hash reference

(F) The value of the C<-options> flag must be a hash reference.

=item Unknown flag "%s" ignored

(W) One of the arguments to C<class> or C<subclass> begins with C<->,
but is not a recognized flag.

=item Unknown option "%s" ignored

(W) The C<-options> flag includes a key/value pair
where the key is not a recognized option.

=back

=head2 Run-Time Diagnostics

If you use the C<-w> flag, your classes will contain code that
can cause the following diagnostics to be emitted:

=over 4

=item %s: Failed assertion: %s

(F) The specified assertion failed.

=item %s: Invalid number of parameters

(F) One of the class' accessors was invoked with
too many or too few parameters.

=item %s: Invalid parameter value

(F) One of the class' accessors was invoked with a parameter
of the wrong type.

=item %s: Member is read-only

(F) Member C<m> was specified read-only,
but C<$o-E<gt>m> was invoked with parameters that looked like
an attempt to set C<m>.

=item %s: Parameter constraint "%s" failed

(F) The constraint for the constructor,
which involves operators,
has failed.

=item %s: Virtual class

(F) The constructor of a virtual class has been directly invoked.

=item %s::new: Invalid "%s" parameter

(F) The class' constructor was invoked with a parameter
of the wrong type.

=item %s::new: Missing "%s" parameter

(F) The class' constructor was invoked without a required parameter.

=item %s::new: Missing or invalid "%s" parameter

(F) The class' constructor was invoked without a required parameter,
or the parameter was not of the correct type
(e.g., hash reference where an array reference is needed,
not a blessed reference to the necessary class).

=back

=head1 SEE ALSO

PERLDIAG(1),
Class::Struct(3)

=head1 COPYRIGHT

Copyright (c) 1999 Steven Wartik. All rights reserved. This program is free
software; you can redistribute it and/or modify it under the same terms as
Perl itself.

=head1 BUGS

Constructors that use the key/value parameter style
detect missing, but not extraneous, keys.

If a default value has side effects,
its behavior varies depending on whether the C<-w> flag is used.

Parameter-passing from a class' constructor
to its superclass' constructor could be smarter.

It would be nice to have selective control of what errors are checked,
rather than the current all-or-nothing model.

=head1 NOTES

Default values that are references cannot be saved to a file.

In C<pre> and C<post> code,
you can access method parameters via C<@_>.
You probably should not do so except for scalar members, though.
For array members, the same code is inserted into I<m> and C<add_>I<m>,
and the code can't tell which method it's in.
Even within method I<m>, the code can't tell if it's looking at a reference
or a value if C<$accept_refs> is true.

The C<UNIVERSAL::isa> function is used to determine if
something is an array or hash reference.
This presents possibilities for metaspecification functions.

This package clearly owes much to C<Class::Struct>.
I thank its creators for their insights.

Speaking of which, unlike C<Class::Struct>,
the C<m> accessor for member C<m> does not return a value when it is set.
This is a deliberate design decision.
If you would like that feature,
you can simulate it for (scalar) member C<m>
by including C<return $m;> as C<post> code.
However, you then short-circuit any assertion for member C<m>.

=cut
