1 package App::Info::Handler;
3 # $Id: Handler.pm,v 1.1 2004-04-29 09:21:28 ivan Exp $
7 App::Info::Handler - App::Info event handler base class
11 use App::Info::Category::FooApp;
12 use App::Info::Handler;
14 my $app = App::Info::Category::FooApp->new( on_info => ['default'] );
18 This class defines the interface for subclasses that wish to handle events
19 triggered by App::Info concrete subclasses. The different types of events
20 triggered by App::Info can all be handled by App::Info::Handler (indeed, by
21 default they're all handled by a single App::Info::Handler object), and
22 App::Info::Handler subclasses may be designed to handle whatever events they
25 If you're interested in I<using> an App::Info event handler, this is probably
26 not the class you should look at, since all it does is define a simple handler
27 that does nothing with an event. Look to the L<App::Info::Handler
28 subclasses|"SEE ALSO"> included in this distribution to do more interesting
29 things with App::Info events.
31 If, on the other hand, you're interested in implementing your own event
37 use vars qw($VERSION);
44 This section documents the public interface of App::Info::Handler.
48 =head3 register_handler
50 App::Info::Handler->register_handler( $key => $code_ref );
52 This class method may be used by App::Info::Handler subclasses to register
53 themselves with App::Info::Handler. Multiple registrations are supported. The
54 idea is that a subclass can define different functionality by specifying
55 different strings that represent different modes of constructing an
56 App::Info::Handler subclass object. The keys are case-sensitve, and should be
57 unique across App::Info::Handler subclasses so that many subclasses can be
58 loaded and used separately. If the C<$key> is already registered,
59 C<register_handler()> will throw an exception. The values are code references
60 that, when executed, return the appropriate App::Info::Handler subclass
65 sub register_handler {
66 my ($pkg, $key, $code) = @_;
67 Carp::croak("Handler '$key' already exists")
69 $handlers{$key} = $code;
73 __PACKAGE__->register_handler('default', sub { __PACKAGE__->new } );
75 ##############################################################################
81 my $handler = App::Info::Handler->new;
82 $handler = App::Info::Handler->new( key => $key);
84 Constructs an App::Info::Handler object and returns it. If the key parameter
85 is provided and has been registered by an App::Info::Handler subclass via the
86 C<register_handler()> class method, then the relevant code reference will be
87 executed and the resulting App::Info::Handler subclass object returned. This
88 approach provides a handy shortcut for having C<new()> behave as an abstract
89 factory method, returning an object of the subclass appropriate to the key
96 my $class = ref $pkg || $pkg;
97 $p{key} ||= 'default';
98 if ($class eq __PACKAGE__ && $p{key} ne 'default') {
99 # We were called directly! Handle it.
100 Carp::croak("No such handler '$p{key}'") unless $handlers{$p{key}};
101 return $handlers{$p{key}}->();
103 # A subclass called us -- just instantiate and return.
104 return bless \%p, $class;
108 =head2 Instance Method
112 $handler->handler($req);
114 App::Info::Handler defines a single instance method that must be defined by
115 its subclasses, C<handler()>. This is the method that will be executed by an
116 event triggered by an App::Info concrete subclass. It takes as its single
117 argument an App::Info::Request object, and returns a true value if it has
118 handled the event request. Returning a false value declines the request, and
119 App::Info will then move on to the next handler in the chain.
121 The C<handler()> method implemented in App::Info::Handler itself does nothing
122 more than return a true value. It thus acts as a very simple default event
123 handler. See the App::Info::Handler subclasses for more interesting handling
124 of events, or create your own!
135 I hatched the idea of the App::Info event model with its subclassable handlers
136 as a way of separating the aggregation of application metadata from writing a
137 user interface for handling certain conditions. I felt it a better idea to
138 allow people to create their own user interfaces, and instead to provide only
139 a few examples. The App::Info::Handler class defines the API interface for
140 handling these conditions, which App::Info refers to as "events".
142 There are various types of events defined by App::Info ("info", "error",
143 "unknown", and "confirm"), but the App::Info::Handler interface is designed to
144 be flexible enough to handle any and all of them. If you're interested in
145 creating your own App::Info event handler, this is the place to learn how.
149 To create an App::Info event handler, all one need do is subclass
150 App::Info::Handler and then implement the C<new()> constructor and the
151 C<handler()> method. The C<new()> constructor can do anything you like, and
152 take any arguments you like. However, I do recommend that the first thing
153 you do in your implementation is to call the super constructor:
157 my $self = $pkg->SUPER::new(@_);
162 Although the default C<new()> constructor currently doesn't do much, that may
163 change in the future, so this call will keep you covered. What it does do is
164 take the parameterized arguments and assign them to the App::Info::Handler
165 object. Thus if you've specified a "mode" argument, where clients can
166 construct objects of you class like this:
168 my $handler = FooHandler->new( mode => 'foo' );
170 You can access the mode parameter directly from the object, like so:
174 my $self = $pkg->SUPER::new(@_);
175 if ($self->{mode} eq 'foo') {
181 Just be sure not to use a parameter key name required by App::Info::Handler
182 itself. At the moment, the only parameter accepted by App::Info::Handler is
183 "key", so in general you'll be pretty safe.
185 Next, I recommend that you take advantage of the C<register_handler()> method
186 to create some shortcuts for creating handlers of your class. For example, say
187 we're creating a handler subclass FooHandler. It has two modes, a default
188 "foo" mode and an advanced "bar" mode. To allow both to be constructed by
189 stringified shortcuts, the FooHandler class implementation might start like
195 use App::Info::Handler;
197 @ISA = qw(App::Info::Handler);
199 foreach my $c (qw(foo bar)) {
200 App::Info::Handler->register_handler
201 ( $c => sub { __PACKAGE__->new( mode => $c) } );
204 The strings "foo" and "bar" can then be used by clients as shortcuts to have
205 App::Info objects automatically create and use handlers for certain events.
206 For example, if a client wanted to use a "bar" event handler for its info
207 events, it might do this:
209 use App::Info::Category::FooApp;
212 my $app = App::Info::Category::FooApp->new(on_info => ['bar']);
214 Take a look at App::Info::Handler::Print and App::Info::Handler::Carp to see
215 concrete examples of C<register_handler()> usage.
217 The final step in creating a new App::Info event handler is to implement the
218 C<handler()> method itself. This method takes a single argument, an
219 App::Info::Request object, and is expected to return true if it handled the
220 request, and false if it did not. The App::Info::Request object contains all
221 the metadata relevant to a request, including the type of event that triggered
222 it; see L<App::Info::Request|App::Info::Request> for its documentation.
224 Use the App::Info::Request object however you like to handle the request
225 however you like. You are, however, expected to abide by a a few guidelines:
231 For error and info events, you are expected (but not required) to somehow
232 display the info or error message for the user. How your handler chooses to do
233 so is up to you and the handler.
237 For unknown and confirm events, you are expected to prompt the user for a
238 value. If it's a confirm event, offer the known value (found in
239 C<$req-E<gt>value>) as a default.
243 For unknown and confirm events, you are expected to call C<$req-E<gt>callback>
244 and pass in the new value. If C<$req-E<gt>callback> returns a false value, you
245 are expected to display the error message in C<$req-E<gt>error> and prompt the
246 user again. Note that C<$req-E<gt>value> calls C<$req-E<gt>callback>
247 internally, and thus assigns the value and returns true if
248 C<$req-E<gt>callback> returns true, and does not assign the value and returns
249 false if C<$req-E<gt>callback> returns false.
253 For unknown and confirm events, if you've collected a new value and
254 C<$req-E<gt>callback> returns true for that value, you are expected to assign
255 the value by passing it to C<$req-E<gt>value>. This allows App::Info to give
256 the value back to the calling App::Info concrete subclass.
260 Probably the easiest way to get started creating new App::Info event handlers
261 is to check out the simple handlers provided with the distribution and follow
262 their logical examples. Consult the App::Info documentation of the L<event
263 methods|App::Info/"Events"> for details on how App::Info constructs the
264 App::Info::Request object for each event type.
268 Report all bugs via the CPAN Request Tracker at
269 L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=App-Info>.
273 David Wheeler <L<david@wheeler.net|"david@wheeler.net">>
277 L<App::Info|App::Info> thoroughly documents the client interface for setting
278 event handlers, as well as the event triggering interface for App::Info
281 L<App::Info::Request|App::Info::Request> documents the interface for the
282 request objects passed to App::Info::Handler C<handler()> methods.
284 The following App::Info::Handler subclasses offer examples for event handler
285 authors, and, of course, provide actual event handling functionality for
290 =item L<App::Info::Handler::Carp|App::Info::Handler::Carp>
292 =item L<App::Info::Handler::Print|App::Info::Handler::Print>
294 =item L<App::Info::Handler::Prompt|App::Info::Handler::Prompt>
298 =head1 COPYRIGHT AND LICENSE
300 Copyright (c) 2002, David Wheeler. All Rights Reserved.
302 This module is free software; you can redistribute it and/or modify it under the
303 same terms as Perl itself.