plucky (3) Badger::Prototype.3pm.gz

Provided by: libbadger-perl_0.16-3_all bug

NAME

       Badger::Prototype - base class for creating prototype classes

SYNOPSIS

           package Badger::Example;
           use base 'Badger::Prototype';

           sub greeting {
               my $self = shift;

               # get prototype object if called as a class method
               $self = $self->prototype() unless ref $self;

               # continue as normal, now $self is an object
               if (@_) {
                   # set greeting if called with args
                   return ($self->{ greeting } = shift);
               }
               else {
                   # otherwise get greeting
                   return $self->{ greeting };
               }
           }

DESCRIPTION

       This module is a subclass of Badger::Base that additionally provides the prototype() method.  It is used
       as a base class for modules that have methods that can be called as either class or object methods.

           # object method
           my $object = Badger::Example->new();
           $object->greeting('Hello World');

           # class method
           Badger::Example->greeting('Hello World');

       The prototype() method returns a singleton object instance which can be used as a default object by
       methods that have been called as class methods.

       Here's an example of a "greeting()" method that can be called with an argument to set a greeting message:

           $object->greeting('Hello World');

       Or without any arguments to get the current message:

           print $object->greeting;            # Hello World

       As well as being called as an object method, we want to be able to call it as a class method:

           Badger::Example->greeting('Hello World');
           print Badger::Example->greeting();  # Hello World

       Here's what the "greeting()" method looks like.

           package Badger::Example;
           use base 'Badger::Prototype';

           sub greeting {
               my $self = shift;

               # get prototype object if called as a class method
               $self = $self->prototype() unless ref $self;

               # continue as normal, now $self is an object
               if (@_) {
                   # set greeting if called with args
                   return ($self->{ greeting } = shift);
               }
               else {
                   # otherwise get greeting
                   return $self->{ greeting };
               }
           }

       We use "ref $self" to determine if "greeting()" has been called as an object method ($self contains an
       object reference) or as a class method ($self contains the class name, in this case "Badger::Example").
       In the latter case, we call prototype() as a class method (remember, $self contains the "Badger::Example"
       class name at this point) to return a prototype object instance which we then store back into $self.

               # get prototype object if called as a class method
               $self = $self->prototype() unless ref $self;

       For the rest of the method we can continue as if called as an object method because $self now contains a
       "Badger::Example" object either way.

       Note that the prototype object reference is stored in the $PROTOTYPE variable in the package of the
       calling object's class.  So if you call prototype on a "Badger::Example::One" object that is subclassed
       from "Badger::Prototype" then the prototype object will be stored in the $Badger::Example::One::PROTOTYPE
       package variable.

METHODS

   prototype(@args)
       Constructor method to create a prototype object and cache it in the $PROTOTYPE package variable for
       subsequent use.  This is usually called from inside methods that can operate as class or object methods,
       as shown in the earlier example.

           sub example {
               my $self = shift;

               # upgrade $self to an object when called as a class method
               $self = $self->prototype() unless ref $self;

               # ...code follows...
           }

       If you prefer a more succinct idiom and aren't too worried about calling the prototype method
       unnecessarily, then you can write it like this:

           sub greeting {
               my $self = shift->prototype;
               # ...code follows...
           }

       If any arguments are passed to the "prototype()" method then it forces a new prototype object to be
       created, replacing any existing one cached in the $PROTOTYPE package variable.  The arguments are
       forwarded to the "new()" constructor method called to create the object.

       If a single undefined value is passed as an argument then any existing prototype is released by setting
       the $PROTOTYPE package variable to "undef".  The existing prototype is then returned, or undef if there
       was no prototype defined.

   has_prototype()
       Returns true or false to indicate if a prototype is defined for a class.  It can be called as a class or
       object method.

AUTHOR

       Andy Wardley <http://wardley.org/>

       Copyright (C) 2006-2009 Andy Wardley.  All Rights Reserved.

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