App-Info

 view release on metacpan or  search on metacpan

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

    $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.

The C<handler()> method implemented in App::Info::Handler itself does nothing
more than return a true value. It thus acts as a very simple default event
handler. See the App::Info::Handler subclasses for more interesting handling
of events, or create your own!

=cut

sub handler { 1 }

1;
__END__

=head1 SUBCLASSING

I hatched the idea of the App::Info event model with its subclassable handlers
as a way of separating the aggregation of application meta data from writing a
user interface for handling certain conditions. I felt it a better idea to
allow people to create their own user interfaces, and instead to provide only
a few examples. The App::Info::Handler class defines the API interface for
handling these conditions, which App::Info refers to as "events".

There are various types of events defined by App::Info ("info", "error",
"unknown", and "confirm"), but the App::Info::Handler interface is designed to
be flexible enough to handle any and all of them. If you're interested in
creating your own App::Info event handler, this is the place to learn how.

=head2 The Interface

To create an App::Info event handler, all one need do is subclass
App::Info::Handler and then implement the C<new()> constructor and the
C<handler()> method. The C<new()> constructor can do anything you like, and
take any arguments you like. However, I do recommend that the first thing
you do in your implementation is to call the super constructor:

  sub new {
      my $pkg = shift;
      my $self = $pkg->SUPER::new(@_);
      # ... other stuff.
      return $self;
  }

Although the default C<new()> constructor currently doesn't do much, that may
change in the future, so this call will keep you covered. What it does do is
take the parameterized arguments and assign them to the App::Info::Handler
object. Thus if you've specified a "mode" argument, where clients can
construct objects of you class like this:

  my $handler = FooHandler->new( mode => 'foo' );

You can access the mode parameter directly from the object, like so:

  sub new {
      my $pkg = shift;
      my $self = $pkg->SUPER::new(@_);
      if ($self->{mode} eq 'foo') {
          # ...
      }
      return $self;
  }

Just be sure not to use a parameter key name required by App::Info::Handler
itself. At the moment, the only parameter accepted by App::Info::Handler is
"key", so in general you'll be pretty safe.

Next, I recommend that you take advantage of the C<register_handler()> method
to create some shortcuts for creating handlers of your class. For example, say
we're creating a handler subclass FooHandler. It has two modes, a default
"foo" mode and an advanced "bar" mode. To allow both to be constructed by
stringified shortcuts, the FooHandler class implementation might start like
this:

  package FooHandler;

  use strict;
  use App::Info::Handler;
  use vars qw(@ISA);
  @ISA = qw(App::Info::Handler);

  foreach my $c (qw(foo bar)) {
      App::Info::Handler->register_handler
        ( $c => sub { __PACKAGE__->new( mode => $c) } );
  }

The strings "foo" and "bar" can then be used by clients as shortcuts to have
App::Info objects automatically create and use handlers for certain events.
For example, if a client wanted to use a "bar" event handler for its info
events, it might do this:

  use App::Info::Category::FooApp;
  use FooHandler;

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

Take a look at App::Info::Handler::Print and App::Info::Handler::Carp to see
concrete examples of C<register_handler()> usage.

The final step in creating a new App::Info event handler is to implement the
C<handler()> method itself. This method takes a single argument, an
App::Info::Request object, and is expected to return true if it handled the
request, and false if it did not. The App::Info::Request object contains all
the meta data relevant to a request, including the type of event that triggered
it; see L<App::Info::Request|App::Info::Request> for its documentation.

Use the App::Info::Request object however you like to handle the request
however you like. You are, however, expected to abide by a a few guidelines:

=over 4

=item *

For error and info events, you are expected (but not required) to somehow
display the info or error message for the user. How your handler chooses to do
so is up to you and the handler.



( run in 2.152 seconds using v1.01-cache-2.11-cpan-98e64b0badf )