File Coverage

blib/lib/App/Info.pm
Criterion Covered Total %
statement 66 94 70.2
branch 14 22 63.6
condition 9 13 69.2
subroutine 19 35 54.2
pod 30 30 100.0
total 138 194 71.1


line stmt bran cond sub pod time code
1             package App::Info;
2              
3             =head1 NAME
4              
5             App::Info - Information about software packages on a system
6              
7             =head1 SYNOPSIS
8              
9             use App::Info::Category::FooApp;
10              
11             my $app = App::Info::Category::FooApp->new;
12              
13             if ($app->installed) {
14             print "App name: ", $app->name, "\n";
15             print "Version: ", $app->version, "\n";
16             print "Bin dir: ", $app->bin_dir, "\n";
17             } else {
18             print "App not installed on your system. :-(\n";
19             }
20              
21             =head1 DESCRIPTION
22              
23             App::Info is an abstract base class designed to provide a generalized
24             interface for subclasses that provide meta data about software packages
25             installed on a system. The idea is that these classes can be used in Perl
26             application installers in order to determine whether software dependencies
27             have been fulfilled, and to get necessary meta data about those software
28             packages.
29              
30             App::Info provides an event model for handling events triggered by App::Info
31             subclasses. The events are classified as "info", "error", "unknown", and
32             "confirm" events, and multiple handlers may be specified to handle any or all
33             of these event types. This allows App::Info clients to flexibly handle events
34             in any way they deem necessary. Implementing new event handlers is
35             straight-forward, and use the triggering of events by App::Info subclasses is
36             likewise kept easy-to-use.
37              
38             A few L are provided with the distribution, but
39             others are invited to write their own subclasses and contribute them to the
40             CPAN. Contributors are welcome to extend their subclasses to provide more
41             information relevant to the application for which data is to be provided (see
42             L for an example), but are
43             encouraged to, at a minimum, implement the abstract methods defined here and
44             in the category abstract base classes (e.g.,
45             L and L).
46             See L for more information on implementing new
47             subclasses.
48              
49             =cut
50              
51 18     18   195266 use strict;
  18         39  
  18         840  
52 18     18   144 use Carp ();
  18         50  
  18         525  
53 18     18   13029 use App::Info::Handler;
  18         42  
  18         436  
54 18     18   15292 use App::Info::Request;
  18         103  
  18         946  
55 18     18   389 use vars qw($VERSION);
  18         33  
  18         44919  
56              
57             $VERSION = '0.57';
58              
59             ##############################################################################
60             ##############################################################################
61             # This code ref is used by the abstract methods to throw an exception when
62             # they're called directly.
63             my $croak = sub {
64             my ($caller, $meth) = @_;
65             $caller = ref $caller || $caller;
66             if ($caller eq __PACKAGE__) {
67             $meth = __PACKAGE__ . '::' . $meth;
68             Carp::croak(__PACKAGE__ . " is an abstract base class. Attempt to " .
69             " call non-existent method $meth");
70             } else {
71             Carp::croak("Class $caller inherited from the abstract base class " .
72             __PACKAGE__ . ", but failed to redefine the $meth() " .
73             "method. Attempt to call non-existent method " .
74             "${caller}::$meth");
75             }
76             };
77              
78             ##############################################################################
79             # This code reference is used by new() and the on_* error handler methods to
80             # set the error handlers.
81             my $set_handlers = sub {
82             my $on_key = shift;
83             # Default is to do nothing.
84             return unless $on_key;
85             my $ref = ref $on_key;
86             if ($ref) {
87             $on_key = [$on_key] unless $ref eq 'ARRAY';
88             # Make sure they're all handlers.
89             foreach my $h (@$on_key) {
90             if (my $r = ref $h) {
91             Carp::croak("$r object is not an App::Info::Handler")
92             unless UNIVERSAL::isa($h, 'App::Info::Handler');
93             } else {
94             # Look up the handler.
95             $h = App::Info::Handler->new( key => $h);
96             }
97             }
98             # Return 'em!
99             return @$on_key;
100             } else {
101             # Look up the handler.
102             return App::Info::Handler->new( key => $on_key);
103             }
104             };
105              
106             ##############################################################################
107             ##############################################################################
108              
109             =head1 INTERFACE
110              
111             This section documents the public interface of App::Info.
112              
113             =head2 Constructor
114              
115             =head3 new
116              
117             my $app = App::Info::Category::FooApp->new(@params);
118              
119             Constructs an App::Info object and returns it. The @params arguments define
120             attributes that can be used to help the App::Info object search for
121             application information on the file system, as well as how the App::Info
122             object will respond to certain events. The event parameters correspond to
123             their like-named methods. See the L<"Event Handler Object Methods"> section
124             for more information on App::Info events and how to handle them. The search
125             parameters that can be passed to C are:
126              
127             =over
128              
129             =item search_exe_names
130              
131             An array reference of possible names for binary executables. These may be used
132             by subclasses to search for application programs that can be used to retrieve
133             application information, such as version numbers. The subclasses generally
134             provide reasonable defaults for most cases.
135              
136             =item search_bin_dirs
137              
138             An array reference of local directories in which to search for executables.
139             These may be used to search for the value of the C attribute in
140             addition to and in preference to the defaults used by each subclass.
141              
142             =item search_lib_names
143              
144             An array reference of possible names for library files. These may be used by
145             subclasses to search for library files for the application. The subclasses
146             generally provide reasonable defaults for most cases.
147              
148             =item search_so_lib_names
149              
150             An array reference of possible names for shared object library files. These
151             may be used by subclasses to search for shared object library files for the
152             application. The subclasses generally provide reasonable defaults for most
153             cases.
154              
155             =item search_lib_dirs
156              
157             An array reference of local directories in which to search for libraries.
158             These may be used to search for the value of the C and C
159             attributes in addition to and in preference to the defaults used by each
160             subclass.
161              
162             =item search_inc_names
163              
164             An array reference of possible names for include files. These may be used by
165             subclasses to search for include files for the application. The subclasses
166             generally provide reasonable defaults for most cases.
167              
168             =item search_inc_dirs
169              
170             An array reference of local directories in which to search for include
171             files. These may be used to search for the value of the C attribute
172             in addition to and in preference to the defaults used by each subclass.
173              
174             =back
175              
176             The parameters to C for the different types of App::Info events are:
177              
178             =over 4
179              
180             =item on_info
181              
182             =item on_error
183              
184             =item on_unknown
185              
186             =item on_confirm
187              
188             =back
189              
190             When passing event handlers to C, the list of handlers for each type
191             should be an anonymous array, for example:
192              
193             my $app = App::Info::Category::FooApp->new( on_info => \@handlers );
194              
195             =cut
196              
197             sub new {
198 55     55 1 21883 my ($pkg, %p) = @_;
199 55   33     544 my $class = ref $pkg || $pkg;
200             # Fail if the method isn't overridden.
201 55 50       194 $croak->($pkg, 'new') if $class eq __PACKAGE__;
202              
203             # Set up handlers.
204 55         157 for (qw(on_error on_unknown on_info on_confirm)) {
205 217         772 $p{$_} = [$set_handlers->($p{$_})];
206             }
207              
208             # Set up search defaults.
209 54         157 for (qw(bin_dirs lib_dirs inc_dirs exe_names lib_names inc_names
210             so_lib_names)) {
211 378         673 local $_ = "search_$_";
212 378 100       907 if (exists $p{$_}) {
213 82 100       461 $p{$_} = [$p{$_}] unless ref $p{$_} eq 'ARRAY';
214             } else {
215 296         1058 $p{$_} = [];
216             }
217             }
218              
219             # Do it!
220 54         592 return bless \%p, $class;
221             }
222              
223             ##############################################################################
224             ##############################################################################
225              
226             =head2 Meta Data Object Methods
227              
228             These are abstract methods in App::Info and must be provided by its
229             subclasses. They provide the essential meta data of the software package
230             supported by the App::Info subclass.
231              
232             =head3 key_name
233              
234             my $key_name = $app->key_name;
235              
236             Returns a string that uniquely identifies the software for which the App::Info
237             subclass provides data. This value should be unique across all App::Info
238             classes. Typically, it's simply the name of the software.
239              
240             =cut
241              
242 1     1 1 14 sub key_name { $croak->(shift, 'key_name') }
243              
244             =head3 installed
245              
246             if ($app->installed) {
247             print "App is installed.\n"
248             } else {
249             print "App is not installed.\n"
250             }
251              
252             Returns a true value if the application is installed, and a false value if it
253             is not.
254              
255             =cut
256              
257 0     0 1 0 sub installed { $croak->(shift, 'installed') }
258              
259             ##############################################################################
260              
261             =head3 name
262              
263             my $name = $app->name;
264              
265             Returns the name of the application.
266              
267             =cut
268              
269 0     0 1 0 sub name { $croak->(shift, 'name') }
270              
271             ##############################################################################
272              
273             =head3 version
274              
275             my $version = $app->version;
276              
277             Returns the full version number of the application.
278              
279             =cut
280              
281             ##############################################################################
282              
283 0     0 1 0 sub version { $croak->(shift, 'version') }
284              
285             =head3 major_version
286              
287             my $major_version = $app->major_version;
288              
289             Returns the major version number of the application. For example, if
290             C returns "7.1.2", then this method returns "7".
291              
292             =cut
293              
294 0     0 1 0 sub major_version { $croak->(shift, 'major_version') }
295              
296             ##############################################################################
297              
298             =head3 minor_version
299              
300             my $minor_version = $app->minor_version;
301              
302             Returns the minor version number of the application. For example, if
303             C returns "7.1.2", then this method returns "1".
304              
305             =cut
306              
307 0     0 1 0 sub minor_version { $croak->(shift, 'minor_version') }
308              
309             ##############################################################################
310              
311             =head3 patch_version
312              
313             my $patch_version = $app->patch_version;
314              
315             Returns the patch version number of the application. For example, if
316             C returns "7.1.2", then this method returns "2".
317              
318             =cut
319              
320 0     0 1 0 sub patch_version { $croak->(shift, 'patch_version') }
321              
322             ##############################################################################
323              
324             =head3 bin_dir
325              
326             my $bin_dir = $app->bin_dir;
327              
328             Returns the full path the application's bin directory, if it exists.
329              
330             =cut
331              
332 0     0 1 0 sub bin_dir { $croak->(shift, 'bin_dir') }
333              
334             ##############################################################################
335              
336             =head3 executable
337              
338             my $executable = $app->executable;
339              
340             Returns the full path the application's bin directory, if it exists.
341              
342             =cut
343              
344 0     0 1 0 sub executable { $croak->(shift, 'executable') }
345              
346             ##############################################################################
347              
348             =head3 inc_dir
349              
350             my $inc_dir = $app->inc_dir;
351              
352             Returns the full path the application's include directory, if it exists.
353              
354             =cut
355              
356 0     0 1 0 sub inc_dir { $croak->(shift, 'inc_dir') }
357              
358             ##############################################################################
359              
360             =head3 lib_dir
361              
362             my $lib_dir = $app->lib_dir;
363              
364             Returns the full path the application's lib directory, if it exists.
365              
366             =cut
367              
368 0     0 1 0 sub lib_dir { $croak->(shift, 'lib_dir') }
369              
370             ##############################################################################
371              
372             =head3 so_lib_dir
373              
374             my $so_lib_dir = $app->so_lib_dir;
375              
376             Returns the full path the application's shared library directory, if it
377             exists.
378              
379             =cut
380              
381 0     0 1 0 sub so_lib_dir { $croak->(shift, 'so_lib_dir') }
382              
383             ##############################################################################
384              
385             =head3 home_url
386              
387             my $home_url = $app->home_url;
388              
389             The URL for the software's home page.
390              
391             =cut
392              
393 0     0 1 0 sub home_url { $croak->(shift, 'home_url') }
394              
395             ##############################################################################
396              
397             =head3 download_url
398              
399             my $download_url = $app->download_url;
400              
401             The URL for the software's download page.
402              
403             =cut
404              
405 0     0 1 0 sub download_url { $croak->(shift, 'download_url') }
406              
407             ##############################################################################
408             ##############################################################################
409              
410             =head2 Search Attributes
411              
412             These methods return lists of things to look for on the local file system when
413             searching for application programs, library files, and include files. They are
414             empty by default, since each subclass generally relies on its own settings,
415             but you can add your own as preferred search parameters by specifying them as
416             parameters to the C constructor.
417              
418             =head3 exe_names
419              
420             my @search_exe_names = $app->search_exe_names;
421              
422             Returns a list of possible names for an executable. Typically used by the
423             C constructor to search for an executable to execute and collect
424             application info.
425              
426             =cut
427              
428 31     31 1 52 sub search_exe_names { @{shift->{search_exe_names}} }
  31         313  
429              
430             ##############################################################################
431              
432             =head3 search_bin_dirs
433              
434             my @search_bin_dirs = $app->search_bin_dirs;
435              
436             Returns a list of possible directories in which to search an executable.
437             Typically used by the C constructor to find an executable to execute
438             and collect application info. The found directory will also generally then
439             be returned by the C method.
440              
441             =cut
442              
443 31     31 1 53 sub search_bin_dirs { @{shift->{search_bin_dirs}} }
  31         1303  
444              
445             ##############################################################################
446              
447             =head3 lib_names
448              
449             my @search_lib_names = $app->search_lib_names;
450              
451             Returns a list of possible names for library files. Typically used by the
452             C method to find library files.
453              
454             =cut
455              
456 6     6 1 13 sub search_lib_names { @{shift->{search_lib_names}} }
  6         32  
457              
458             ##############################################################################
459              
460             =head3 so_lib_names
461              
462             my @search_so_lib_names = $app->search_so_lib_names;
463              
464             Returns a list of possible names for library files. Typically used by the
465             C method to find shared object library files.
466              
467             =cut
468              
469 4     4 1 11 sub search_so_lib_names { @{shift->{search_so_lib_names}} }
  4         20  
470              
471             ##############################################################################
472              
473             =head3 search_lib_dirs
474              
475             my @search_lib_dirs = $app->search_lib_dirs;
476              
477             Returns a list of possible directories in which to search for libraries.
478             Typically used by the C and C methods to find
479             library files.
480              
481             =cut
482              
483 14     14 1 29 sub search_lib_dirs { @{shift->{search_lib_dirs}} }
  14         120  
484              
485             ##############################################################################
486              
487             =head3 inc_names
488              
489             my @search_inc_names = $app->search_inc_names;
490              
491             Returns a list of possible names for include files. Typically used by the
492             C method to find include files.
493              
494             =cut
495              
496 7     7 1 41 sub search_inc_names { @{shift->{search_inc_names}} }
  7         95  
497              
498             ##############################################################################
499              
500             =head3 search_inc_dirs
501              
502             my @search_inc_dirs = $app->search_inc_dirs;
503              
504             Returns a list of possible directories in which to search for includes.
505             Typically used by the C method to find include files.
506              
507             =cut
508              
509 11     11 1 20 sub search_inc_dirs { @{shift->{search_inc_dirs}} }
  11         91  
510              
511             ##############################################################################
512             ##############################################################################
513              
514             =head2 Event Handler Object Methods
515              
516             These methods provide control over App::Info event handling. Events can be
517             handled by one or more objects of subclasses of App::Info::Handler. The first
518             to return a true value will be the last to execute. This approach allows
519             handlers to be stacked, and makes it relatively easy to create new handlers.
520             L for information on writing event
521             handlers.
522              
523             Each of the event handler methods takes a list of event handlers as its
524             arguments. If none are passed, the existing list of handlers for the relevant
525             event type will be returned. If new handlers are passed in, they will be
526             returned.
527              
528             The event handlers may be specified as one or more objects of the
529             App::Info::Handler class or subclasses, as one or more strings that tell
530             App::Info construct such handlers itself, or a combination of the two. The
531             strings can only be used if the relevant App::Info::Handler subclasses have
532             registered strings with App::Info. For example, the App::Info::Handler::Print
533             class included in the App::Info distribution registers the strings "stderr"
534             and "stdout" when it starts up. These strings may then be used to tell
535             App::Info to construct App::Info::Handler::Print objects that print to STDERR
536             or to STDOUT, respectively. See the App::Info::Handler subclasses for what
537             strings they register with App::Info.
538              
539             =head3 on_info
540              
541             my @handlers = $app->on_info;
542             $app->on_info(@handlers);
543              
544             Info events are triggered when the App::Info subclass wants to send an
545             informational status message. By default, these events are ignored, but a
546             common need is for such messages to simply print to STDOUT. Use the
547             L class included with the
548             App::Info distribution to have info messages print to STDOUT:
549              
550             use App::Info::Handler::Print;
551             $app->on_info('stdout');
552             # Or:
553             my $stdout_handler = App::Info::Handler::Print->new('stdout');
554             $app->on_info($stdout_handler);
555              
556             =cut
557              
558             sub on_info {
559 6     6 1 11 my $self = shift;
560 6 100       25 @{ $self->{on_info} } = $set_handlers->(\@_) if @_;
  3         15  
561 6         8 return @{ $self->{on_info} };
  6         30  
562             }
563              
564             =head3 on_error
565              
566             my @handlers = $app->on_error;
567             $app->on_error(@handlers);
568              
569             Error events are triggered when the App::Info subclass runs into an unexpected
570             but not fatal problem. (Note that fatal problems will likely throw an
571             exception.) By default, these events are ignored. A common way of handling
572             these events is to print them to STDERR, once again using the
573             L class included with the
574             App::Info distribution:
575              
576             use App::Info::Handler::Print;
577             my $app->on_error('stderr');
578             # Or:
579             my $stderr_handler = App::Info::Handler::Print->new('stderr');
580             $app->on_error($stderr_handler);
581              
582             Another approach might be to turn such events into fatal exceptions. Use the
583             included L class for this
584             purpose:
585              
586             use App::Info::Handler::Carp;
587             my $app->on_error('croak');
588             # Or:
589             my $croaker = App::Info::Handler::Carp->new('croak');
590             $app->on_error($croaker);
591              
592             =cut
593              
594             sub on_error {
595 0     0 1 0 my $self = shift;
596 0 0       0 @{ $self->{on_error} } = $set_handlers->(\@_) if @_;
  0         0  
597 0         0 return @{ $self->{on_error} };
  0         0  
598             }
599              
600             =head3 on_unknown
601              
602             my @handlers = $app->on_unknown;
603             $app->on_uknown(@handlers);
604              
605             Unknown events are triggered when the App::Info subclass cannot find the value
606             to be returned by a method call. By default, these events are ignored. A
607             common way of handling them is to have the application prompt the user for the
608             relevant data. The App::Info::Handler::Prompt class included with the
609             App::Info distribution can do just that:
610              
611             use App::Info::Handler::Prompt;
612             my $app->on_unknown('prompt');
613             # Or:
614             my $prompter = App::Info::Handler::Prompt;
615             $app->on_unknown($prompter);
616              
617             See L for information
618             on how it works.
619              
620             =cut
621              
622             sub on_unknown {
623 0     0 1 0 my $self = shift;
624 0 0       0 @{ $self->{on_unknown} } = $set_handlers->(\@_) if @_;
  0         0  
625 0         0 return @{ $self->{on_unknown} };
  0         0  
626             }
627              
628             =head3 on_confirm
629              
630             my @handlers = $app->on_confirm;
631             $app->on_confirm(@handlers);
632              
633             Confirm events are triggered when the App::Info subclass has found an
634             important piece of information (such as the location of the executable it'll
635             use to collect information for the rest of its methods) and wants to confirm
636             that the information is correct. These events will most often be triggered
637             during the App::Info subclass object construction. Here, too, the
638             App::Info::Handler::Prompt class included with the App::Info distribution can
639             help out:
640              
641             use App::Info::Handler::Prompt;
642             my $app->on_confirm('prompt');
643             # Or:
644             my $prompter = App::Info::Handler::Prompt;
645             $app->on_confirm($prompter);
646              
647             =cut
648              
649             sub on_confirm {
650 0     0 1 0 my $self = shift;
651 0 0       0 @{ $self->{on_confirm} } = $set_handlers->(\@_) if @_;
  0         0  
652 0         0 return @{ $self->{on_confirm} };
  0         0  
653             }
654              
655             ##############################################################################
656             ##############################################################################
657              
658             =head1 SUBCLASSING
659              
660             As an abstract base class, App::Info is not intended to be used directly.
661             Instead, you'll use concrete subclasses that implement the interface it
662             defines. These subclasses each provide the meta data necessary for a given
663             software package, via the interface outlined above (plus any additional
664             methods the class author deems sensible for a given application).
665              
666             This section describes the facilities App::Info provides for subclassing. The
667             goal of the App::Info design has been to make subclassing straight-forward, so
668             that developers can focus on gathering the data they need for their
669             application and minimize the work necessary to handle unknown values or to
670             confirm values. As a result, there are essentially three concepts that
671             developers need to understand when subclassing App::Info: organization,
672             utility methods, and events.
673              
674             =head2 Organization
675              
676             The organizational idea behind App::Info is to name subclasses by broad
677             software categories. This approach allows the categories themselves to
678             function as abstract base classes that extend App::Info, so that they can
679             specify more methods for all of their base classes to implement. For example,
680             App::Info::HTTPD has specified the C abstract method that its
681             subclasses must implement. So as you get ready to implement your own subclass,
682             think about what category of software you're gathering information about.
683             New categories can be added as necessary.
684              
685             =head2 Utility Methods
686              
687             Once you've decided on the proper category, you can start implementing your
688             App::Info concrete subclass. As you do so, take advantage of App::Info::Util,
689             wherein I've tried to encapsulate common functionality to make subclassing
690             easier. I found that most of what I was doing repetitively was looking for
691             files and directories, and searching through files. Thus, App::Info::Util
692             subclasses L in order to offer easy access to
693             commonly-used methods from that class, e.g., C. Plus, it has several
694             of its own methods to assist you in finding files and directories in lists of
695             files and directories, as well as methods for searching through files and
696             returning the values found in those files. See
697             L for more information, and the App::Info
698             subclasses in this distribution for usage examples.
699              
700             I recommend the use of a package-scoped lexical App::Info::Util object. That
701             way it's nice and handy when you need to carry out common tasks. If you find
702             you're doing something over and over that's not already addressed by an
703             App::Info::Util method, consider submitting a patch to App::Info::Util to add
704             the functionality you need.
705              
706             =head2 Events
707              
708             Use the methods described below to trigger events. Events are designed to
709             provide a simple way for App::Info subclass developers to send status messages
710             and errors, to confirm data values, and to request a value when the class
711             cannot determine a value itself. Events may optionally be handled by module
712             users who assign App::Info::Handler subclass objects to your App::Info
713             subclass object using the event handling methods described in the L<"Event
714             Handler Object Methods"> section.
715              
716             =cut
717              
718             ##############################################################################
719             # This code reference is used by the event methods to manage the stack of
720             # event handlers that may be available to handle each of the events.
721             my $handler = sub {
722             my ($self, $meth, $params) = @_;
723              
724             # Sanity check. We really want to keep control over this.
725             Carp::croak("Cannot call protected method $meth()")
726             unless UNIVERSAL::isa($self, scalar caller(1));
727              
728             # Create the request object.
729             $params->{type} ||= $meth;
730             my $req = App::Info::Request->new(%$params);
731              
732             # Do the deed. The ultimate handling handler may die.
733             foreach my $eh (@{$self->{"on_$meth"}}) {
734             last if $eh->handler($req);
735             }
736              
737             # Return the request.
738             return $req;
739             };
740              
741             ##############################################################################
742              
743             =head3 info
744              
745             $self->info(@message);
746              
747             Use this method to display status messages for the user. You may wish to use
748             it to inform users that you're searching for a particular file, or attempting
749             to parse a file or some other resource for the data you need. For example, a
750             common use might be in the object constructor: generally, when an App::Info
751             object is created, some important initial piece of information is being
752             sought, such as an executable file. That file may be in one of many locations,
753             so it makes sense to let the user know that you're looking for it:
754              
755             $self->info("Searching for executable");
756              
757             Note that, due to the nature of App::Info event handlers, your informational
758             message may be used or displayed any number of ways, or indeed not at all (as
759             is the default behavior).
760              
761             The C<@message> will be joined into a single string and stored in the
762             C attribute of the App::Info::Request object passed to info event
763             handlers.
764              
765             =cut
766              
767             sub info {
768 131     131 1 299 my $self = shift;
769             # Execute the handler sequence.
770 131         1365 my $req = $handler->($self, 'info', { message => join '', @_ });
771             }
772              
773             ##############################################################################
774              
775             =head3 error
776              
777             $self->error(@error);
778              
779             Use this method to inform the user that something unexpected has happened. An
780             example might be when you invoke another program to parse its output, but it's
781             output isn't what you expected:
782              
783             $self->error("Unable to parse version from `/bin/myapp -c`");
784              
785             As with all events, keep in mind that error events may be handled in any
786             number of ways, or not at all.
787              
788             The C<@erorr> will be joined into a single string and stored in the C
789             attribute of the App::Info::Request object passed to error event handlers. If
790             that seems confusing, think of it as an "error message" rather than an "error
791             error." :-)
792              
793             =cut
794              
795             sub error {
796 12     12 1 21 my $self = shift;
797             # Execute the handler sequence.
798 12         54 my $req = $handler->($self, 'error', { message => join '', @_ });
799             }
800              
801             ##############################################################################
802              
803             =head3 unknown
804              
805             my $val = $self->unknown(@params);
806              
807             Use this method when a value is unknown. This will give the user the option --
808             assuming the appropriate handler handles the event -- to provide the needed
809             data. The value entered will be returned by C. The parameters are
810             as follows:
811              
812             =over 4
813              
814             =item key
815              
816             The C parameter uniquely identifies the data point in your class, and is
817             used by App::Info to ensure that an unknown event is handled only once, no
818             matter how many times the method is called. The same value will be returned by
819             subsequent calls to C as was returned by the first call, and no
820             handlers will be activated. Typical values are "version" and "lib_dir".
821              
822             =item prompt
823              
824             The C parameter is the prompt to be displayed should an event handler
825             decide to prompt for the appropriate value. Such a prompt might be something
826             like "Path to your httpd executable?". If this parameter is not provided,
827             App::Info will construct one for you using your class' C method
828             and the C parameter. The result would be something like "Enter a valid
829             FooApp version". The C parameter value will be stored in the
830             C attribute of the App::Info::Request object passed to event
831             handlers.
832              
833             =item callback
834              
835             Assuming a handler has collected a value for your unknown data point, it might
836             make sense to validate the value. For example, if you prompt the user for a
837             directory location, and the user enters one, it makes sense to ensure that the
838             directory actually exists. The C parameter allows you to do this. It
839             is a code reference that takes the new value or values as its arguments, and
840             returns true if the value is valid, and false if it is not. For the sake of
841             convenience, the first argument to the callback code reference is also stored
842             in C<$_> .This makes it easy to validate using functions or operators that,
843             er, operate on C<$_> by default, but still allows you to get more information
844             from C<@_> if necessary. For the directory example, a good callback might be
845             C. The C parameter code reference will be stored in the
846             C attribute of the App::Info::Request object passed to event
847             handlers.
848              
849             =item error
850              
851             The error parameter is the error message to display in the event that the
852             C code reference returns false. This message may then be used by the
853             event handler to let the user know what went wrong with the data she entered.
854             For example, if the unknown value was a directory, and the user entered a
855             value that the C identified as invalid, a message to display might
856             be something like "Invalid directory path". Note that if the C
857             parameter is not provided, App::Info will supply the generic error message
858             "Invalid value". This value will be stored in the C attribute of the
859             App::Info::Request object passed to event handlers.
860              
861             =back
862              
863             This may be the event method you use most, as it should be called in every
864             meta data method if you cannot provide the data needed by that method. It will
865             typically be the last part of the method. Here's an example demonstrating each
866             of the above arguments:
867              
868             my $dir = $self->unknown( key => 'lib_dir',
869             prompt => "Enter lib directory path",
870             callback => sub { -d },
871             error => "Not a directory");
872              
873             =cut
874              
875             sub unknown {
876 20     20 1 1534 my ($self, %params) = @_;
877 20 100       444 my $key = $params{key}
878             or Carp::croak("No key parameter passed to unknown()");
879             # Just return the value if we've already handled this value. Ideally this
880             # shouldn't happen.
881 19 100       118 return $self->{__unknown__}{$key} if exists $self->{__unknown__}{$key};
882              
883             # Create a prompt and error message, if necessary.
884 18   66     160 $params{message} = delete $params{prompt} ||
885             "Enter a valid " . $self->key_name . " $key";
886 18   100     108 $params{error} ||= 'Invalid value';
887              
888             # Execute the handler sequence.
889 18         71 my $req = $handler->($self, "unknown", \%params);
890              
891             # Mark that we've provided this value and then return it.
892 18         229 $self->{__unknown__}{$key} = $req->value;
893 18         176 return $self->{__unknown__}{$key};
894             }
895              
896             ##############################################################################
897              
898             =head3 confirm
899              
900             my $val = $self->confirm(@params);
901              
902             This method is very similar to C, but serves a different purpose.
903             Use this method for significant data points where you've found an appropriate
904             value, but want to ensure it's really the correct value. A "significant data
905             point" is usually a value essential for your class to collect meta data values.
906             For example, you might need to locate an executable that you can then call to
907             collect other data. In general, this will only happen once for an object --
908             during object construction -- but there may be cases in which it is needed
909             more than that. But hopefully, once you've confirmed in the constructor that
910             you've found what you need, you can use that information to collect the data
911             needed by all of the meta data methods and can assume that they'll be right
912             because that first, significant data point has been confirmed.
913              
914             Other than where and how often to call C, its use is quite similar
915             to that of C. Its parameters are as follows:
916              
917             =over
918              
919             =item key
920              
921             Same as for C, a string that uniquely identifies the data point in
922             your class, and ensures that the event is handled only once for a given key.
923             The same value will be returned by subsequent calls to C as was
924             returned by the first call for a given key.
925              
926             =item prompt
927              
928             Same as for C. Although C is called to confirm a value,
929             typically the prompt should request the relevant value, just as for
930             C. The difference is that the handler I use the C
931             parameter as the default should the user not provide a value. The C
932             parameter will be stored in the C attribute of the App::Info::Request
933             object passed to event handlers.
934              
935             =item value
936              
937             The value to be confirmed. This is the value you've found, and it will be
938             provided to the user as the default option when they're prompted for a new
939             value. This value will be stored in the C attribute of the
940             App::Info::Request object passed to event handlers.
941              
942             =item callback
943              
944             Same as for C. Because the user can enter data to replace the
945             default value provided via the C parameter, you might want to validate
946             it. Use this code reference to do so. The callback will be stored in the
947             C attribute of the App::Info::Request object passed to event
948             handlers.
949              
950             =item error
951              
952             Same as for C: an error message to display in the event that a
953             value entered by the user isn't validated by the C code reference.
954             This value will be stored in the C attribute of the App::Info::Request
955             object passed to event handlers.
956              
957             =back
958              
959             Here's an example usage demonstrating all of the above arguments:
960              
961             my $exe = $self->confirm( key => 'shell',
962             prompt => 'Path to your shell?',
963             value => '/bin/sh',
964             callback => sub { -x },
965             error => 'Not an executable');
966              
967              
968             =cut
969              
970             sub confirm {
971 39     39 1 1949 my ($self, %params) = @_;
972 39 100       642 my $key = $params{key}
973             or Carp::croak("No key parameter passed to confirm()");
974 38 50       191 return $self->{__confirm__}{$key} if exists $self->{__confirm__}{$key};
975              
976             # Create a prompt and error message, if necessary.
977 38   66     211 $params{message} = delete $params{prompt} ||
978             "Enter a valid " . $self->key_name . " $key";
979 38   100     133 $params{error} ||= 'Invalid value';
980              
981             # Execute the handler sequence.
982 38         132 my $req = $handler->($self, "confirm", \%params);
983              
984             # Mark that we've confirmed this value.
985 38         3144 $self->{__confirm__}{$key} = $req->value;
986              
987 38         415 return $self->{__confirm__}{$key}
988             }
989              
990             1;
991             __END__