App::I...andler(3pm)

πŸ“¦
version 0.57 Β· 2 versions
  • 0.57 Β· debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking (latest)
  • 0.57 Β· ubuntu jammy
, in debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking

πŸ’– App::Info::Handler β€” the event handler base class, bestie πŸ’–

okay so real talk: this page is App::Info::Handler, a Perl module living in the user-contributed Perl docs, and it's the base class you build App::Info event handlers on top of. it's giving ✨foundation✨. let's get into it.


🌈 SYNOPSIS 🌈

use App::Info::Category::FooApp;
use App::Info::Handler;

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

πŸ¦‹ DESCRIPTION πŸ¦‹

so this class defines the interface for subclasses that wanna handle events triggered by App::Info concrete subclasses. and like, every single type of event that App::Info fires off can be handled by App::Info::Handler β€” no cap, by default they're all handled by one single App::Info::Handler object β€” and App::Info::Handler subclasses can be designed to handle literally whatever events they want. flexible queen behavior πŸ’…

now. if you're here because you wanna use an App::Info event handler? bestie, this is probably not the class you should be looking at 😭 because all it does is define a simple handler that does nothing with an event. the way that it just sits there. instead, go look at the App::Info::Handler subclasses that ship with this distribution β€” those are the ones doing the interesting stuff with App::Info events.

if, on the other hand, you're here because you wanna implement your own event handlers? πŸ‘‘ oh you're in the right place. read on!


✨ INTERFACE ✨

this section documents the public interface of App::Info::Handler. let's go.

πŸŽ€ Class Method

register_handler

App::Info::Handler->register_handler( $key => $code_ref );

this class method is for App::Info::Handler subclasses that wanna register themselves with App::Info::Handler. and yes, multiple registrations are supported β€” collect them all 🫢

the whole idea is that a subclass can define different functionality by specifying different strings, and those strings represent different modes of constructing an App::Info::Handler subclass object. the keys are case-sensitive, and they should be unique across all App::Info::Handler subclasses so that a bunch of subclasses can be loaded and used separately. if the $key is already registered, register_handler() will throw an exception πŸ’€ so don't do that. the values are code references that, when executed, return the appropriate App::Info::Handler subclass object.

🌸 Constructor

new

my $handler = App::Info::Handler->new;
$handler =  App::Info::Handler->new( key => $key);

constructs an App::Info::Handler object and hands it back to you. and here's the cute part: if the key parameter is provided and it's been registered by an App::Info::Handler subclass via the register_handler() class method, then the relevant code reference gets executed and you get the resulting App::Info::Handler subclass object instead. so new() is lowkey acting as an abstract factory method β€” returning whatever subclass object matches the key parameter. handy shortcut, iconic really ⭐

πŸ’œ Instance Method

handler

$handler->handler($req);

App::Info::Handler defines a single instance method that must be defined by its subclasses: handler(). this is the method that gets 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 handled the event request. returning a false value means you're declining the request, and App::Info will then move on to the next handler in the chain. no hard feelings.

the handler() method implemented in App::Info::Handler itself does literally nothing more than return a true value. so it acts as a very simple default event handler. go check the App::Info::Handler subclasses for more interesting event handling β€” or make your own! πŸ’…


🧚 SUBCLASSING 🧚

okay storytime: the idea of the App::Info event model with its subclassable handlers was hatched as a way of separating the aggregation of application meta data from writing a user interface for handling certain conditions. the vibe was: let people create their own user interfaces, and just provide a few examples instead. the App::Info::Handler class defines the API interface for handling these conditions, which App::Info calls "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. πŸŽ“

🌟 The Interface

to create an App::Info event handler, all you gotta do is subclass App::Info::Handler and then implement the new() constructor and the handler() method. the new() constructor can do anything you like and take any arguments you like. however, the strong recommendation is that the first thing you do in your implementation is call the super constructor:

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

the default new() constructor currently doesn't do much, but that may change in the future, so making this call keeps you covered. what it does do is take the parameterized arguments and assign them to the App::Info::Handler object. so if you've specified a mode argument, where clients can construct objects of your class like this:

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

then 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 that's 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 up, the recommendation is to take advantage of the 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']);

go take a look at App::Info::Handler::Print and App::Info::Handler::Carp to see concrete examples of register_handler() usage. πŸ”

the final step in creating a new App::Info event handler is to implement the 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 App::Info::Request for its documentation.

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

  • 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.
  • For unknown and confirm events, you are expected to prompt the user for a value. if it's a confirm event, offer the known value (found in $req->value) as a default.
  • For unknown and confirm events, you are expected to call $req->callback and pass in the new value. if $req->callback returns a false value, you are expected to display the error message in $req->error and prompt the user again. note that $req->value calls $req->callback internally, and thus assigns the value and returns true if $req->callback returns true, and does not assign the value and returns false if $req->callback returns false.
  • For unknown and confirm events, if you've collected a new value and $req->callback returns true for that value, you are expected to assign the value by passing it to $req->value. this allows App::Info to give the value back to the calling App::Info concrete subclass.

probably the easiest way to get started creating new App::Info event handlers is to check out the simple handlers provided with the distribution and follow their logical examples. consult the App::Info documentation of the event methods for details on how App::Info constructs the App::Info::Request object for each event type. 🫢


πŸŽ€ SUPPORT πŸŽ€

this module is stored in an open GitHub repository <http://github.com/theory/app-info/>. feel free to fork and contribute! the audacity, the generosity, we love to see it.

please file bug reports via GitHub Issues <http://github.com/theory/app-info/issues/> or by sending mail to bug-App-Info@rt.cpan.org <mailto:bug-App-Info@rt.cpan.org>.


πŸ‘‘ AUTHOR πŸ‘‘

David E. Wheeler <david@justatheory.com>


🌈 SEE ALSO 🌈

App::Info thoroughly documents the client interface for setting event handlers, as well as the event triggering interface for App::Info concrete subclasses.

App::Info::Request documents the interface for the request objects passed to App::Info::Handler handler() methods.

the following App::Info::Handler subclasses offer examples for event handler authors, and, of course, provide actual event handling functionality for App::Info clients:

  • App::Info::Handler::Carp
  • App::Info::Handler::Print
  • App::Info::Handler::Prompt

Copyright (c) 2002-2011, David E. Wheeler. Some Rights Reserved.

this module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.


and that's the whole page, bestie!! πŸ’…βœ¨ this one shipped with perl v5.36.0 and got stamped with the date 2022-12-06 β€” so yeah, vintage but still slaying. mwah, go write a handler, you've got this πŸ«ΆπŸŽ€

πŸ“¦ where this page comes from