Class-GAPI
view release on metacpan or search on metacpan
<pre>
$pet->sprout('magician', tophat => 'bunny') ; # $pet->{'magician'} is now a Class::GAPI object</pre>
<pre>
my $wascallywabit = $pet->magician->tophat() ; # get the rabbit
$pet->magician->tophat('dove') ; # replace it with a dove</pre>
<p>Now, back to the constructor:</p>
<pre>
my $pet = Guppy->new(foo => "bar") ;</pre>
<p>This does not just set $pet->{'foo'} to ``bar'', it invoke the function 'foo' on ``bar'', and
the autoloaded function is what does the set/get. So it is important to note that one can preempt
this behavior simply by defining a function as follows:</p>
<pre>
sub foo {
my $self = shift ;
my $bar = shift ;
print "a guppy walks into a $bar and says: Ouch.\n" ;
}</pre>
<p>
</p>
<hr />
<h1><a name="object_initialization">OBJECT INITIALIZATION</a></h1>
<p>Class::GAPI has three stages of initialization at constructor time. The first which we just
discussed is by calling passed arguments as functions. The second is by evaluating two class
wide predefined arrays. They are:</p>
<pre>
our @Default_Properties = qw(scaly small sushi) ; # execute some functions during new()
our @Children = qw(Class::GAPI::Fin Class::List::Eyeballs) ; # make some branches on our tree</pre>
<p>@Default_Properties is easy. Anything named here is called just as if it was passed as an
option with an undefined value. So the example above is the same as:</p>
<pre>
my $pet = Guppy->new(scaly => undef, small => undef, sushi => undef) ;</pre>
<p>@Default_Properties is not used that often, in that the other Initialization stages can
do more than @Default_Properties. It is handy from time to time when you want to add
something complicated to the objects initialization and don't need to pass any special
arguments. (Like I said, rarely used) It is also trumped by any same-named passed option
pair from stage 1. So you you can define this as a hail marry for any function that should
be run at constructor time, even if the caller doesn't send an option pair.</p>
<p>@Children is a list of subordinate objects to call -><code>new()</code> on at constructor time. This allows
Class::GAPI based objects to include other classes in a sem-codeless fashion. Just ``use'' something
and stick it in Children, and you will get one built. (No options will be passed, but it will
built.) So for example you can do this:</p>
<pre>
package Guppy ;</pre>
<pre>
use CGI ;
use Class::GAPI ;
our @ISA = qw(Class::GAPI) ;
our @Children = qw(CGI) ;
1 ;</pre>
<p>Which will then allow you to do this:</p>
<pre>
my $pet = Guppy->new() ;
my $SwimTowardstheLight = $pet->CGI->param("fishhook") ; # Extract CGI parameter "fishhook"
Class::GAPI will always use the right-most namespace fragment as the option in the option => value pair. (This may
cause a namespace conflict from time to time, in those cases just use the third stage _init instead.) So for example:</pre>
<pre>
package SpyGuppy ;
use Crypt::CBC ; # block handler
use Crypt::DES ; # Encryption Algorythm.
use Class::GAPI ;
our @ISA = qw(Class::GAPI) ;
our @Children = qw(Crypt::CBC Crypt::DES) ;
1 ;</pre>
<p>and then do:</p>
<pre>
my $pet = SpyGuppy->new() ;
$pet->CBC->something() ;
$pet->DES->somethingelse() ;</pre>
<p>@Children also conveiniently has 2 special class names. Class::GAPI::Foo, and Class::List::Foo. In
this case ``Foo'' can be anything you like, and will correspondingly be used to create a
sprout()ed object. Note that Class::GAPI::Foo is a a sprouted hash, while Class::List::Foo
is a sprouted array. This is very convenient for making lists of objects. The technique below can be used
to quickly create a variety of styles of record manager classes.</p>
<pre>
package Guppy::School ;
use Guppy ;
our @ISA = qw(Guppy) ; # We are derived from a Guppy, which is derived from a GAPI
our @Children = qw(Class::List::School) ; # $self->{'School'} is now an array</pre>
<pre>
sub doSpawn { # Add a new Guppy Object
my $self = shift ;
my $fish = Guppy->new() ;
push @{$self->School()}, $fish ;
}</pre>
<pre>
sub fishNet { # Get a specific Guppy object
my $self = shift ;
my $n = shift ;
my $fish = $self->School->[$n] ;
return($fish) ;
}
1 ;</pre>
<p>The third stage of initialization is by defining a local &_init subroutine. This gets called after everything else. So if one desires to
do something with passed variables after the class is blessed, this is where to do it. If you call an autoloaded function here, it takes place
after autoloaded functions from ->new(), and Default_Properties. So you do have access to data passed or processed during invokation.</p>
<p>passed at invokation:</p>
<pre>
package Guppy ;
use Class::GAPI ;
our @ISA = (Class::GAPI);
use strict ;
sub _init {
my $self = shift ;
$self->chopchopchop() if $self->sushi() && $self->filet() ;
}
1 ;</pre>
<pre>
package PetShop ;
use Guppy ;</pre>
<pre>
my $pet = Guppy->new(-sushi => 0, -filet => undef) ;
my $lunch = Guppy->new(-sushi => 1, -filet => 1) ;</pre>
<p>In this case the execution of method chopchopchop would occur
in the case of lunch but not in the case of pet.</p>
<p>
</p>
<hr />
<h1><a name="other_functions">OTHER FUNCTIONS</a></h1>
<p>Cloning is supported for Class::GAPI objects and any subordinate objects based on Class::GAPI
or that Inherit Class::GAPI. This includes Class::List objects. This is function is eval()d, so it
will not crash if you have other stuff in their, just don't expect that other stuff copy.</p>
( run in 0.516 second using v1.01-cache-2.11-cpan-39bf76dae61 )