App-Info

 view release on metacpan or  search on metacpan

lib/App/Info/Handler.pm  view on Meta::CPAN

package App::Info::Handler;

=head1 NAME

App::Info::Handler - App::Info event handler base class

=head1 SYNOPSIS

  use App::Info::Category::FooApp;
  use App::Info::Handler;

  my $app = App::Info::Category::FooApp->new( on_info => ['default'] );

=head1 DESCRIPTION

This class defines the interface for subclasses that wish to handle events
triggered by App::Info concrete subclasses. The different types of events
triggered by App::Info can all be handled by App::Info::Handler (indeed, by
default they're all handled by a single App::Info::Handler object), and
App::Info::Handler subclasses may be designed to handle whatever events they
wish.

If you're interested in I<using> an App::Info event handler, this is probably
not the class you should look at, since all it does is define a simple handler
that does nothing with an event. Look to the L<App::Info::Handler
subclasses|"SEE ALSO"> included in this distribution to do more interesting
things with App::Info events.

If, on the other hand, you're interested in implementing your own event
handlers, read on!

=cut

use strict;
use vars qw($VERSION);
$VERSION = '0.57';

my %handlers;

=head1 INTERFACE

This section documents the public interface of App::Info::Handler.

=head2 Class Method

=head3 register_handler

  App::Info::Handler->register_handler( $key => $code_ref );

This class method may be used by App::Info::Handler subclasses to register
themselves with App::Info::Handler. Multiple registrations are supported. The
idea is that a subclass can define different functionality by specifying
different strings that represent different modes of constructing an
App::Info::Handler subclass object. The keys are case-sensitive, and should be
unique across App::Info::Handler subclasses so that many subclasses can be
loaded and used separately. If the C<$key> is already registered,
C<register_handler()> will throw an exception. The values are code references
that, when executed, return the appropriate App::Info::Handler subclass
object.

=cut

sub register_handler {
    my ($pkg, $key, $code) = @_;
    Carp::croak("Handler '$key' already exists")
      if $handlers{$key};
    $handlers{$key} = $code;
}

# Register ourself.
__PACKAGE__->register_handler('default', sub { __PACKAGE__->new } );

##############################################################################

=head2 Constructor

=head3 new

  my $handler = App::Info::Handler->new;
  $handler =  App::Info::Handler->new( key => $key);

Constructs an App::Info::Handler object and returns it. If the key parameter
is provided and has been registered by an App::Info::Handler subclass via the
C<register_handler()> class method, then the relevant code reference will be
executed and the resulting App::Info::Handler subclass object returned. This
approach provides a handy shortcut for having C<new()> behave as an abstract
factory method, returning an object of the subclass appropriate to the key
parameter.

=cut

sub new {
    my ($pkg, %p) = @_;
    my $class = ref $pkg || $pkg;
    $p{key} ||= 'default';
    if ($class eq __PACKAGE__ && $p{key} ne 'default') {
        # We were called directly! Handle it.
        Carp::croak("No such handler '$p{key}'") unless $handlers{$p{key}};
        return $handlers{$p{key}}->();
    } else {
        # A subclass called us -- just instantiate and return.
        return bless \%p, $class;
    }
}

=head2 Instance Method

=head3 handler

  $handler->handler($req);

App::Info::Handler defines a single instance method that must be defined by
its subclasses, C<handler()>. This is the method that will be executed by an
event triggered by an App::Info concrete subclass. It takes as its single
argument an App::Info::Request object, and returns a true value if it has
handled the event request. Returning a false value declines the request, and
App::Info will then move on to the next handler in the chain.



( run in 1.400 second using v1.01-cache-2.11-cpan-39bf76dae61 )