=head1 NAME Class::Generate - Generate Perl class hierarchies =head1 SYNOPSIS use Class::Generate qw(class subclass delete_class); # 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. $value = $obj->last_a; # Return last element 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. $obj->delete_h($key); # Delete slot occupied by $key. @keys = $obj->h_keys; # Access keys of member h. @values = $obj->h_values; # Access values of member h. $another = $obj->copy; # Copy an object. if ( $obj->equals($another) ) { ... } # Test equality. subclass s => [ ], -parent => 'class_name'; =head1 DESCRIPTION The C 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 function. The C 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. This package must not exist when C 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 with two scalar members, C and C. If the type is followed by an identifier, the identifier is assumed to be a class name, and 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 and C<$Class_Name> are equivalent. The class need not be declared using the C package. =head1 CREATING INSTANCES Each class that you generate has a constructor named C. Invoking the constructor creates an instance of the class. You may provide C with parameters to set the values of members: class Person => [ name => '$', age => '$' ]; $p = Person->new; # Neither name nor age is 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. 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 form is used, the member must be a reference blessed to the named class or to one of its subclasses. The method will C (see L) if the argument is not a blessed reference to an instance of C 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 or one of its subclasses. An array member has four associated methods: =over 4 =item C With no argument, C returns the member's whole array. With one argument, C's behavior depends on whether the argument is an array reference. If it is not, then the argument must be an integer I, and C returns element I of the member. If no such element exists, C returns C. 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. The second argument is assigned to element I of the member. =item C This method appends its arguments to the member's array. =item C This method returns the index of the last element in the array. =item C This method returns the last element of C, or C if C has no elements. It's a shorthand for C<$o-Earray_mem($o-Earray_mem_size)>. =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. print $p->kids($p->kids_size)->name; # Prints 'Porky Pig'. print $p->last_kids->name; # So does this. =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 or one of its subclasses. A hash member has four associated methods: =over 4 =item C With no arguments, C returns the member's whole hash. With one argument that is a hash reference, the member's value becomes the key/value pairs in that reference. With one argument that is a string, the element of the hash keyed by that string is returned. If no such element exists, C returns C. With two arguments, the second argument is assigned to the hash, keyed by the string representation of the first argument. =item C The C method returns all keys associated with the member. =item C The C method returns all values associated with the member. =item C The C method takes one or more arguments. It deletes from C's hash all elements matching the arguments. =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. This method undefines a member C. =head1 OBJECT INSTANCE METHODS C also generates methods that you can invoke on an object instance. These are as follows: =head2 Copy Use the C method to copy the value of an object. The expression: $p = $o->copy; assigns to C<$p> a copy of C<$o>. Members of C<$o> that are classes (or arrays or hashes of classes) are copied using their own C method. =head2 Equals Use the C method to test the equality of two object instances: if ( $o1->equals($o2) ) { ... } The two object instances are equal if members that have values in C<$o1> have equal values in C<$o2>, and vice versa. Equality is tested as you would expect: two scalar members are equal if they have the same value; two array members are equal if they have the same elements; two hash members are equal if they have the same key/value pairs. If a member's value is restricted to a class, then equality is tested using that class' C method. Otherwise, it is tested using the C operator. By default, all members participate in the equality test. If one or more members possess true values for the C attribute, then only those members participate in the equality test. You can override this definition of equality. See L. =head1 ADVANCED MEMBER SPECIFICATIONS As shown, you specify each member as a Cvalue> pair. If the C 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 a member: =over 4 =item type=>string If you use a hash reference for a member's value, you I use the C attribute to specify its type: scalar_member => { type => '$' } =item required=>boolean If the C 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 for the member. =item default=>value The C 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 => { # Default value is all UIDs type => '@', # currently in /etc/passwd. default => 'do { local $/ = undef; open PASSWD, "/etc/passwd"; [ map {(split(/:/))[2]} split /\n/, ] }' } }; Specify hash members analogously. The value is evaluated each time the constructor is invoked. In C, the default value for C can change between invocations. If the default value is a reference rather than a string, it is not re-evaluated. In the following, default values for C and C are based on the members of C<@default_value> each time Cnew> is invoked, whereas C's default value is set when the C function is invoked to define C: @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). There are two more things to know about default values that are strings. First, if a member is typed, the C function evaluates its (string-based) default value to ensure that it is of the correct type for the member. Be aware of this if your default value has side effects (and see L). Second, the context of the default value is the C method of the package generated to implement your class. That's why C in C, above, needs the name of the current package in its default value. =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 its accessor. Within C code, you can refer to members as if they were 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. The trailing semicolon used to be required, but everyone forgot it. As of version 1.06 it's optional: C<'$age*=2'> is accepted and equivalent to C<'$age*=2;'> (but see L<"BUGS">). You reference array and hash members as usual (except for testing for definition; see L<"BUGS">). 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. Prefix them with a C<&>: class Bar => [ m1 => { type => '@', post => '&undef_m1;' }, m2 => { type => '%', post => '@m1 = &m2_keys;' } ]; $o = new Bar; $o->m1([1, 2, 3]); # m1 is still undefined. $o->m2({a => 1, b => 2}); # Now m1 is qw(a b). =item pre=>code The C
 key is similar to the C key,
but it is executed just before an member is changed.
It is I executed if the member is only accessed.
The C
 and C code have the same scope,
which lets you share variables.
For instance:

    class Foo => [
	mem => { type => '$', pre => 'my $v = $mem;', post => 'return $v;' }
    ];
    $o = new Foo;
    $p = $o->mem(1);	# Sets $p to undef.
    $q = $o->mem(2);	# Sets $q to 1.

is a way to return the previous value of C any time it's modified
(but see L<"NOTES">).

=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.
The expression will be tested any time
the member is modified through its accessors.
Your code will C 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 code associated with the member.

=item private=>boolean

If the C 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.
A private member can, however, be accessed in C, C
, and C
code of other members of the class.

=item protected=>boolean

If the C attribute is true,
the member cannot be accessed outside the class or any of its subclasses.
A protected member can, however, be accessed in C, C
, and C
code of other members of the class or its subclasses.

=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 CI accessor is not defined for the member,
nor are other accessors that might modify the member.
(Code in C can set it, however.)

=item key=>boolean

If this attribute is true, then the member participates in equality tests.
See L<"Equals">.

=item nocopy=>value

The C attribute gives you some per-member control
over how the C method.
If C is false (the default),
the original's value is copied as described in L<"Copy">.
If C is true,
the original's value is assigned rather than copied;
in other words, the copy and the original will have the same value
if the original's value is a reference.

=back

=head1 AFFECTING THE CONSTRUCTOR

You may include a C 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, and exactly one of C or C.
Note that the names are I prefixed with C<$>, C<@>, or C<%>.

Specifying a list of constraints as an array reference can be clunky.
The C 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 attribute:

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

However, C<'name & (height ^ weight)'> would not work.
The C 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.
Use whichever form works best for you.

=item post=>string of code

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

The C
 key is I recognized in C.

=item assert=>expression

The C key's value is inserted
just after the C 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),
the string is included as a comment just before
the member's methods.

=item style=>style definition

The C