Class-GAPI

 view release on metacpan or  search on metacpan

GAPI.html  view on Meta::CPAN

<pre>

        $pet-&gt;sprout('magician', tophat =&gt; 'bunny')        ; # $pet-&gt;{'magician'} is now a Class::GAPI object</pre>
<pre>
        my $wascallywabit = $pet-&gt;magician-&gt;tophat()       ; # get the rabbit  
        $pet-&gt;magician-&gt;tophat('dove')                     ; # replace it with a dove</pre>
<p>Now, back to the constructor:</p>
<pre>
        my $pet = Guppy-&gt;new(foo =&gt; &quot;bar&quot;) ;</pre>
<p>This does not just set $pet-&gt;{'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 &quot;a guppy walks into a $bar and says: Ouch.\n&quot; ;
        }</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-&gt;new(scaly =&gt; undef, small =&gt; undef, sushi =&gt; 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 -&gt;<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-&gt;new()      ; 
        my $SwimTowardstheLight = $pet-&gt;CGI-&gt;param(&quot;fishhook&quot;) ; # Extract CGI parameter &quot;fishhook&quot; 
 
Class::GAPI will always use the right-most namespace fragment as the option in the option =&gt; 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-&gt;new()       ; 
        $pet-&gt;CBC-&gt;something()          ;
        $pet-&gt;DES-&gt;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-&gt;{'School'} is now an array</pre>
<pre>
        sub doSpawn { # Add a new Guppy Object
                my $self = shift                         ;       
                my $fish = Guppy-&gt;new()          ; 
                push @{$self-&gt;School()}, $fish ; 
        }</pre>
<pre>
        sub fishNet { # Get a specific Guppy object 
                my $self = shift                 ; 
                my $n = shift                    ; 
                my $fish = $self-&gt;School-&gt;[$n] ;
                return($fish)                    ;   
        }
        1 ;</pre>
<p>The third stage of initialization is by defining a local &amp;_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 -&gt;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-&gt;chopchopchop() if $self-&gt;sushi() &amp;&amp; $self-&gt;filet() ; 
        }
        1 ;</pre>
<pre>
        package PetShop ; 
        use Guppy       ;</pre>
<pre>
        my $pet = Guppy-&gt;new(-sushi =&gt; 0, -filet =&gt; undef) ; 
        my $lunch = Guppy-&gt;new(-sushi =&gt; 1, -filet =&gt; 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 )