File Coverage

blib/lib/App/Info/Handler.pm
Criterion Covered Total %
statement 16 17 94.1
branch 5 6 83.3
condition 5 8 62.5
subroutine 4 5 80.0
pod 3 3 100.0
total 33 39 84.6


line stmt bran cond sub pod time code
1             package App::Info::Handler;
2              
3             =head1 NAME
4              
5             App::Info::Handler - App::Info event handler base class
6              
7             =head1 SYNOPSIS
8              
9             use App::Info::Category::FooApp;
10             use App::Info::Handler;
11              
12             my $app = App::Info::Category::FooApp->new( on_info => ['default'] );
13              
14             =head1 DESCRIPTION
15              
16             This class defines the interface for subclasses that wish to handle events
17             triggered by App::Info concrete subclasses. The different types of events
18             triggered by App::Info can all be handled by App::Info::Handler (indeed, by
19             default they're all handled by a single App::Info::Handler object), and
20             App::Info::Handler subclasses may be designed to handle whatever events they
21             wish.
22              
23             If you're interested in I an App::Info event handler, this is probably
24             not the class you should look at, since all it does is define a simple handler
25             that does nothing with an event. Look to the L
26             subclasses|"SEE ALSO"> included in this distribution to do more interesting
27             things with App::Info events.
28              
29             If, on the other hand, you're interested in implementing your own event
30             handlers, read on!
31              
32             =cut
33              
34 18     18   217174 use strict;
  18         42  
  18         724  
35 18     18   93 use vars qw($VERSION);
  18         37  
  18         6545  
36             $VERSION = '0.57';
37              
38             my %handlers;
39              
40             =head1 INTERFACE
41              
42             This section documents the public interface of App::Info::Handler.
43              
44             =head2 Class Method
45              
46             =head3 register_handler
47              
48             App::Info::Handler->register_handler( $key => $code_ref );
49              
50             This class method may be used by App::Info::Handler subclasses to register
51             themselves with App::Info::Handler. Multiple registrations are supported. The
52             idea is that a subclass can define different functionality by specifying
53             different strings that represent different modes of constructing an
54             App::Info::Handler subclass object. The keys are case-sensitive, and should be
55             unique across App::Info::Handler subclasses so that many subclasses can be
56             loaded and used separately. If the C<$key> is already registered,
57             C will throw an exception. The values are code references
58             that, when executed, return the appropriate App::Info::Handler subclass
59             object.
60              
61             =cut
62              
63             sub register_handler {
64 28     28 1 172 my ($pkg, $key, $code) = @_;
65 28 50       420 Carp::croak("Handler '$key' already exists")
66             if $handlers{$key};
67 28         176 $handlers{$key} = $code;
68             }
69              
70             # Register ourself.
71             __PACKAGE__->register_handler('default', sub { __PACKAGE__->new } );
72              
73             ##############################################################################
74              
75             =head2 Constructor
76              
77             =head3 new
78              
79             my $handler = App::Info::Handler->new;
80             $handler = App::Info::Handler->new( key => $key);
81              
82             Constructs an App::Info::Handler object and returns it. If the key parameter
83             is provided and has been registered by an App::Info::Handler subclass via the
84             C class method, then the relevant code reference will be
85             executed and the resulting App::Info::Handler subclass object returned. This
86             approach provides a handy shortcut for having C behave as an abstract
87             factory method, returning an object of the subclass appropriate to the key
88             parameter.
89              
90             =cut
91              
92             sub new {
93 30     30 1 447 my ($pkg, %p) = @_;
94 30   33     259 my $class = ref $pkg || $pkg;
95 30   100     151 $p{key} ||= 'default';
96 30 100 66     140 if ($class eq __PACKAGE__ && $p{key} ne 'default') {
97             # We were called directly! Handle it.
98 8 100       133 Carp::croak("No such handler '$p{key}'") unless $handlers{$p{key}};
99 7         29 return $handlers{$p{key}}->();
100             } else {
101             # A subclass called us -- just instantiate and return.
102 22         127 return bless \%p, $class;
103             }
104             }
105              
106             =head2 Instance Method
107              
108             =head3 handler
109              
110             $handler->handler($req);
111              
112             App::Info::Handler defines a single instance method that must be defined by
113             its subclasses, C. This is the method that will be executed by an
114             event triggered by an App::Info concrete subclass. It takes as its single
115             argument an App::Info::Request object, and returns a true value if it has
116             handled the event request. Returning a false value declines the request, and
117             App::Info will then move on to the next handler in the chain.
118              
119             The C method implemented in App::Info::Handler itself does nothing
120             more than return a true value. It thus acts as a very simple default event
121             handler. See the App::Info::Handler subclasses for more interesting handling
122             of events, or create your own!
123              
124             =cut
125              
126 0     0 1   sub handler { 1 }
127              
128             1;
129             __END__