NAME

POE::Sugar::Attributes - Subrouting Attributes for common POE tasks

SYNOPSIS

The following is mainly copy/pasted from demo.pl in the distribution

use POE::Sugar::Attributes qw(wire_current_session wire_new_session);
use base qw(POE::Sugar::Attributes);
use POE;
use POE::Session;
use POE::Kernel;
use Log::Fu;

sub say_alias : Event
{
    my ($alias_name,$do_stop) = @_[ARG0,ARG1];
    log_infof("I was passed %s", $alias_name);
    if(!$do_stop) {
        $_[KERNEL]->post($alias_name, say_alias => $alias_name, 1);
    }
}

sub my_event :Event(foo_event, bar_event)
{
    log_warnf("I'm called as %s.", $_[STATE]);
}

sub tick :Recurring(Interval => 2)
{
    log_info("Tick");
}

sub tock :Recurring(Interval => 1)
{
    log_info("Tock");
}

sub hello :Start
{
    log_info("Beginning");
    $_[KERNEL]->post($_[SESSION], $_, "Hi")
        for (qw(foo_event bar_event));
    $_[KERNEL]->yield(say_alias => "session alias", 0);
}

sub byebye :Stop
{
    log_warnf("We're stopping");
}

POE::Session->create(inline_states => POE::Sugar::Attributes->inline_states);
POE::Kernel->run();

ATTRIBUTES

Event, Event(list,of,names)

Specify that this subroutine will act as an event. In the first form, the name of the subroutine itself is the event name. In the second form, the function will be the target of all the listed events (but not the function name itself, unless it is also included in the list).

:Event may be specified multiple times

Recurring(Interval => $seconds, [Name => 'event_name;])

Specify that this is a recurring timer. It will be called every Interval until the session terminates, or the timer is manually removed (using the POE::Kernel::delay) method.

A new event will be added which will default to the subroutine name. If you wish to use different name, add the Name key with the preferred event name as the value.

Internally, the function is wrapped around with code which looks like this:

$poe_kernel->delay($evname, $interval);
goto &{$symname};

If during execution there is need to remove the event, you can do something like

sub nag :Recurring(Interval => 3600) {
    if($dont_nag) {
        $_[KERNEL]->delay($_[STATE], undef);
    } else {
        #....
    }
}

SigHandler(SIGNAL,LIST)

This function will act as a signal handler for those signals specified in the signal list. Each signal in the list is a signal name recognized by POE. See POE::Kernel for more information on the signals and the arguments they take

Catcher

This is an exception handler. This will do the equivalent of

$poe_kernel->state(subname => \&subname)
$poe_kernel->sig(DIE => subname)

Doing :SigHandler(DIE) will produce a similar effect

Reaper

This is a handler for SIGCHLD

Start

Indicate that this function will be invoked as POE::Session's _start event.

Stop

Indicate that this function will be invoked as POE::Session's _stop event.

WIRING

In order to have your attributed subroutines behave as expected, it is needed to call one of the wiring functions, so that POE will know about the new events that you have created.

There are two functions, exported on request, or accessible via their POE::Attribues namespace

POE::Sugar::Attributes->wire_current_session(kernel, [pkgname])

Call this during a running session to add new events. _start and _stop handlers will not be wired, but all others will.

pkgname is the name of the package in which the attributed subroutines were defined. If this is not specified, it is assumed to be the calling package

POE::Sugar::Attributes->wire_new_session(alias, [pkgname])

Call this to initialize a new session. alias is the desired alias for your session, or undef to disable an alias.

pkgname has the semantics as in wire_current_session

POE::Sugar::Attributes->inline_states(pkgname, [alias])

This returns a hash reference, which can be used as so:

POE::Session->create(
    inline_states => POE::Sugar::Attributes->inline_states()
);

The pkgname and alias parameters have the same semantics as in the previous functions.

RATIONALE

POE itself is quite light in terms of the syntactic sugar it provides. There are some nice wrappers, such as MooseX::POE and POE::Declare, but they provide a heavier layer of abstraction.

This module was intended so that one can keep the same calling and argument conventions of POE itself, while trying to avoid boilerplate for common tasks.

Another possibility with this module, that really does not exist with alternatives, is the ease of maintaining 'mixins'. Mixins are modules which reside outside of the main session, but are logically part of it - and do not need the management overhead of creating a new session.

SEE ALSO

There are quite a few modules out there which have intended to something similar but are either incomplete, too basic, or require much more baggage

POE::Session::Attribute

POE::Session::AttributeBased

AUTHOR AND COPYRIGHT

Copyright (c) 2011 by M. Nunberg

You may use and distribute this module under the same terms and conditions as perl itself.