App-Info
view release on metacpan or search on metacpan
lib/App/Info.pm view on Meta::CPAN
$self->error(@error);
Use this method to inform the user that something unexpected has happened. An
example might be when you invoke another program to parse its output, but it's
output isn't what you expected:
$self->error("Unable to parse version from `/bin/myapp -c`");
As with all events, keep in mind that error events may be handled in any
number of ways, or not at all.
The C<@erorr> will be joined into a single string and stored in the C<message>
attribute of the App::Info::Request object passed to error event handlers. If
that seems confusing, think of it as an "error message" rather than an "error
error." :-)
=cut
sub error {
my $self = shift;
# Execute the handler sequence.
my $req = $handler->($self, 'error', { message => join '', @_ });
}
##############################################################################
=head3 unknown
my $val = $self->unknown(@params);
Use this method when a value is unknown. This will give the user the option --
assuming the appropriate handler handles the event -- to provide the needed
data. The value entered will be returned by C<unknown()>. The parameters are
as follows:
=over 4
=item key
The C<key> parameter uniquely identifies the data point in your class, and is
used by App::Info to ensure that an unknown event is handled only once, no
matter how many times the method is called. The same value will be returned by
subsequent calls to C<unknown()> as was returned by the first call, and no
handlers will be activated. Typical values are "version" and "lib_dir".
=item prompt
The C<prompt> parameter is the prompt to be displayed should an event handler
decide to prompt for the appropriate value. Such a prompt might be something
like "Path to your httpd executable?". If this parameter is not provided,
App::Info will construct one for you using your class' C<key_name()> method
and the C<key> parameter. The result would be something like "Enter a valid
FooApp version". The C<prompt> parameter value will be stored in the
C<message> attribute of the App::Info::Request object passed to event
handlers.
=item callback
Assuming a handler has collected a value for your unknown data point, it might
make sense to validate the value. For example, if you prompt the user for a
directory location, and the user enters one, it makes sense to ensure that the
directory actually exists. The C<callback> parameter allows you to do this. It
is a code reference that takes the new value or values as its arguments, and
returns true if the value is valid, and false if it is not. For the sake of
convenience, the first argument to the callback code reference is also stored
in C<$_> .This makes it easy to validate using functions or operators that,
er, operate on C<$_> by default, but still allows you to get more information
from C<@_> if necessary. For the directory example, a good callback might be
C<sub { -d }>. The C<callback> parameter code reference will be stored in the
C<callback> attribute of the App::Info::Request object passed to event
handlers.
=item error
The error parameter is the error message to display in the event that the
C<callback> code reference returns false. This message may then be used by the
event handler to let the user know what went wrong with the data she entered.
For example, if the unknown value was a directory, and the user entered a
value that the C<callback> identified as invalid, a message to display might
be something like "Invalid directory path". Note that if the C<error>
parameter is not provided, App::Info will supply the generic error message
"Invalid value". This value will be stored in the C<error> attribute of the
App::Info::Request object passed to event handlers.
=back
This may be the event method you use most, as it should be called in every
meta data method if you cannot provide the data needed by that method. It will
typically be the last part of the method. Here's an example demonstrating each
of the above arguments:
my $dir = $self->unknown( key => 'lib_dir',
prompt => "Enter lib directory path",
callback => sub { -d },
error => "Not a directory");
=cut
sub unknown {
my ($self, %params) = @_;
my $key = $params{key}
or Carp::croak("No key parameter passed to unknown()");
# Just return the value if we've already handled this value. Ideally this
# shouldn't happen.
return $self->{__unknown__}{$key} if exists $self->{__unknown__}{$key};
# Create a prompt and error message, if necessary.
$params{message} = delete $params{prompt} ||
"Enter a valid " . $self->key_name . " $key";
$params{error} ||= 'Invalid value';
# Execute the handler sequence.
my $req = $handler->($self, "unknown", \%params);
# Mark that we've provided this value and then return it.
$self->{__unknown__}{$key} = $req->value;
return $self->{__unknown__}{$key};
}
##############################################################################
=head3 confirm
my $val = $self->confirm(@params);
This method is very similar to C<unknown()>, but serves a different purpose.
Use this method for significant data points where you've found an appropriate
value, but want to ensure it's really the correct value. A "significant data
point" is usually a value essential for your class to collect meta data values.
For example, you might need to locate an executable that you can then call to
collect other data. In general, this will only happen once for an object --
during object construction -- but there may be cases in which it is needed
more than that. But hopefully, once you've confirmed in the constructor that
you've found what you need, you can use that information to collect the data
needed by all of the meta data methods and can assume that they'll be right
because that first, significant data point has been confirmed.
Other than where and how often to call C<confirm()>, its use is quite similar
to that of C<unknown()>. Its parameters are as follows:
=over
=item key
Same as for C<unknown()>, a string that uniquely identifies the data point in
your class, and ensures that the event is handled only once for a given key.
The same value will be returned by subsequent calls to C<confirm()> as was
returned by the first call for a given key.
=item prompt
Same as for C<unknown()>. Although C<confirm()> is called to confirm a value,
typically the prompt should request the relevant value, just as for
C<unknown()>. The difference is that the handler I<should> use the C<value>
parameter as the default should the user not provide a value. The C<prompt>
parameter will be stored in the C<message> attribute of the App::Info::Request
object passed to event handlers.
=item value
The value to be confirmed. This is the value you've found, and it will be
provided to the user as the default option when they're prompted for a new
value. This value will be stored in the C<value> attribute of the
App::Info::Request object passed to event handlers.
=item callback
Same as for C<unknown()>. Because the user can enter data to replace the
default value provided via the C<value> parameter, you might want to validate
it. Use this code reference to do so. The callback will be stored in the
C<callback> attribute of the App::Info::Request object passed to event
handlers.
=item error
Same as for C<unknown()>: an error message to display in the event that a
value entered by the user isn't validated by the C<callback> code reference.
This value will be stored in the C<error> attribute of the App::Info::Request
object passed to event handlers.
=back
Here's an example usage demonstrating all of the above arguments:
my $exe = $self->confirm( key => 'shell',
prompt => 'Path to your shell?',
value => '/bin/sh',
callback => sub { -x },
error => 'Not an executable');
=cut
sub confirm {
my ($self, %params) = @_;
my $key = $params{key}
or Carp::croak("No key parameter passed to confirm()");
return $self->{__confirm__}{$key} if exists $self->{__confirm__}{$key};
# Create a prompt and error message, if necessary.
$params{message} = delete $params{prompt} ||
"Enter a valid " . $self->key_name . " $key";
$params{error} ||= 'Invalid value';
# Execute the handler sequence.
my $req = $handler->($self, "confirm", \%params);
# Mark that we've confirmed this value.
$self->{__confirm__}{$key} = $req->value;
return $self->{__confirm__}{$key}
}
1;
__END__
=head2 Event Examples
Below I provide some examples demonstrating the use of the event methods.
These are meant to emphasize the contexts in which it's appropriate to use
them.
Let's start with the simplest, first. Let's say that to find the version
number for an application, you need to search a file for the relevant data.
Your App::Info concrete subclass might have a private method that handles this
work, and this method is the appropriate place to use the C<info()> and, if
necessary, C<error()> methods.
sub _find_version {
my $self = shift;
# Try to find the revelant file. We cover this method below.
# Just return if we cant' find it.
my $file = $self->_find_file('version.conf') or return;
# Send a status message.
$self->info("Searching '$file' file for version");
( run in 1.147 second using v1.01-cache-2.11-cpan-39bf76dae61 )