Badger::Factory::Class - class module for Badger::Factory sub-classes


Badger documentation Contained in the Badger distribution.

Index


Code Index:

NAME

Top

Badger::Factory::Class - class module for Badger::Factory sub-classes

SYNOPSIS

Top

This module can be used to create subclasses of Badger::Factory.

    package My::Widgets;

    use Badger::Factory::Class
        version => 0.01,
        item    => 'widget',
        path    => 'My::Widget Your::Widget',
        widgets => {
            extra => 'Another::Widget::Module',
            super => 'Golly::Gosh',
        };

    package main;

    # class method
    my $widget = My::Widgets->widget( foo => @args );

    # object method
    my $widgets = My::Widgets->new;
    my $widget  = $widgets->widget( foo => @args );

DESCRIPTION

Top

This module is a subclass of Badger::Class specialised for the purpose of creating Badger::Factory subclasses. It is used by the Badger::Codecs module among others.

METHODS

Top

The following methods are provided in addition to those inherited from the Badger::Class base class.

item($name)

The singular name of the item that the factory manages. This is used to set the $ITEM package variable for Badger::Factory to use.

items($name)

The plural name of the item that the factory manages. This is used to set the $ITEMS package variable for Badger::Factory to use.

path($name)

A list of module names that form the search path when loading modules. This will set the relevant package variable depending on the value of $ITEMS (or the regular plural form of $ITEM if $ITEMS is undefined). For example, is $ITEMS is set to widgets then this method will set $WIDGETS_PATH.

AUTHOR

Top

Andy Wardley http://wardley.org/

COPYRIGHT

Top

SEE ALSO

Top

Badger::Factory, Badger::Codecs


Badger documentation Contained in the Badger distribution.

#========================================================================
#
# Badger::Factory::Class
#
# DESCRIPTION
#   Subclass of Badger::Class for creating Badger::Factory sub-classes.
#
# AUTHOR
#   Andy Wardley   <abw@wardley.org>
#
#========================================================================

package Badger::Factory::Class;

use Carp;
use Badger::Class
    version   => 0.01,
    debug     => 0,
    uber      => 'Badger::Class',
    hooks     => 'item path',
    words     => 'ITEM ITEMS',
    utils     => 'plural',
    import    => 'CLASS',
    constants => 'DELIMITER ARRAY HASH',
    constant  => {
        PATH_SUFFIX => '_PATH',
        FACTORY     => 'Badger::Factory',
    };
#    exports   => {
#        fail  => _export_fail_hook,
#    };

CLASS->export_fail(\&_export_fail_hook);

# catch a hook that has the same name as the items, i.e. widgets

sub _export_fail_hook {
    my ($class, $target, $symbol, $symbols) = @_;
    my $klass = class($target, $class);
    my $items = $klass->var(ITEMS);

    # look for $ITEMS or fall back on plural($ITEM)
    unless ($items) {
        my $item = $klass->var(ITEM);
        $items = plural($item) if $item;
    }

#    $target->debug("looking for $items to match $symbol\n");

    # if the import symbols matches $items (e.g. widgets) then push the 
    # next argument into the relevant package var (e.g. $WIDGETS)
    if ($items && $items eq $symbol) {
        croak "You didn't specify a value for the '$items' load option."
            unless @$symbols;
        $klass->var( uc($items) => shift @$symbols );
    }
    else {
        $class->_export_fail($target, $symbol, $symbols);
    }
}

sub item {
    my ($self, $item) = @_;
    $self->base(FACTORY);
    $self->var( ITEM => $item );
    return $self;
}

sub items {
    my ($self, $items) = @_;
    $self->base(FACTORY);
    $self->var( ITEMS => $items );
    return $self;
}

sub path {
    my ($self, $path) = @_;
    my $type = $self->var(ITEM)
        || croak "\$ITEM is not defined for $self.  Please add an 'item' option";
    my $var = uc($type) . PATH_SUFFIX;

    $path = [ split(DELIMITER, $path) ]
        unless ref $path eq ARRAY;

    $self->debug("adding $var => [", join(', ', @$path), "]") if DEBUG;
    $self->base(FACTORY);

    # we use import_symbol() rather than var() so that it gets declared 
    # properly, thus avoiding undefined symbol warnings
    $self->import_symbol( $var => \$path );
    
    return $self;
}


# Local Variables:
# mode: perl
# perl-indent-level: 4
# indent-tabs-mode: nil
# End:
#
# vim: expandtab shiftwidth=4:



1;