Badger

 view release on metacpan or  search on metacpan

lib/Badger/Class/Methods.pm  view on Meta::CPAN

equivalent to:

    sub init {
        my ($self, $config) = @_;
        $self->{ config } = $config;
        $self->init_foo($config);
        $self->init_bar($config);
        return $self;
    }

It's up to you to implement the C<init_foo()> and C<init_bar()> methods,
or to inherit them from a base class or mixin.

=head2 slots($class,$methods)

This method can be used to define methods for list-based object classes.
A list, reference to a list, or string of whitespace delimited method
names should be passed an argument(s).  A method will be generated for
each item specified.  The first method will reference the first (0th) item
in the list, the second method will reference the second (1st), and so on.

    Badger::Class::Methods->slots('My::Module', 'foo bar');
    Badger::Class::Methods->slots('My::Module', 'foo', 'bar');
    Badger::Class::Methods->slots('My::Module', ['foo', 'bar']);

It is usually called indirectly via the L<slots|Badger::Class/slots>
export hook in L<Badger::Class>.

    package Badger::Example;
    
    use Badger::Class
        slots => 'size colour object';
    
    sub new {
        my ($class, @stuff) = @_;
        bless \@stuff, $class;
    }

The above example defines a simple list-based object class with three
slots: C<size>, C<colour> and C<object>.  You can use it like this:

    my $bus = Badger::Test::Slots->new(qw( big red bus ));
    
    print $bus->size;       # big
    print $bus->colour;     # red
    print $bus->object;     # bus

The methods generated are mutators.  That is, you can pass an argument
to update the slot value.

    $bus->size('large');

=head2 auto_can($class,$method)

This can be used to define a method that automatically generates other
methods on demand.  

Suppose you have a view class that renders a view of a tree. In classic
I<double dispatch> style, each node in the tree calls a method against the
view object corresponding to the node's type. A C<text> node calls
C<$view-E<gt>view_text($self)>, a C<bold> node calls
C<$view-E<gt>view_bold($self)>, and so on (we're assuming that this is some
kind of document object model we're rendering, but it could apply to
anything).

Our view methods might look something like this:

    sub view_text {
        my ($self, $node) = @_;
        print "TEXT: $node\n";
    }

    sub view_bold {
        my ($self, $node) = @_;
        print "BOLD: $node\n";
    }

This can get rather repetitive and boring if you've got lots of different
node types.  So instead of defining all the methods manually, you can declare
an C<auto_can> method that will create methods on demand.

    use Badger::Class
        auto_can => 'can_view';
        
    sub can_view {
        my ($self, $name) = @_;
        my $NAME = uc $name;
        
        return sub {
            my ($self, $node) = @_;
            print "$NAME: $node";
        }
    }

The method should return a subroutine reference or any false value if it
declines to generate a method.  For example, you might want to limit the 
generator method to only creating methods that match a particular format.

    sub can_view {
        my ($self, $name) = @_;
        
        # only create methods that are prefixed with 'view_'
        if ($name =~ s/^view_//) {
            my $NAME = uc $name;
            
            return sub {
                my ($self, $node) = @_;
                print "$NAME: $node";
            }
        }
        else {
            return undef;
        }
    }

The C<auto_can()> method adds C<AUTOLOAD()> and C<can()> methods to your 
class.  The C<can()> method first looks to see if the method is pre-defined
(i.e. it does what the default C<can()> method does).  If it isn't, it then
calls the C<can_view()> method that we've declared using the C<auto_can> 
option (you can call your method C<auto_can()> if you like, but in this 
case we're calling it C<can_view()> just to be different).  The end result
is that you can call C<can()> and it will generate any missing methods on
demand.

    # this calls can_view() which returns a CODE sub 
    my $method = $object->can('view_italic');

The C<AUTOLOAD()> method is invoked whenever you call a method that 
doesn't exist.  It calls the C<can()> method to automatically generate 
the method and then installs the new method in the package's symbol table.
The next time you call the method it will be there waiting for you.  There's
no need for the C<AUTOLOAD()> method to get involved from that point on.



( run in 0.945 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )