Parts of a POE program

The simplest POE program consists of two modules and some custom code: POE::Kernel, POE::Session, and the event handlers that use them.

About POE::Kernel

POE::Kernel provides event based representations of OS kernel services. These include I/O events, alarms and other timed events, signal events, and several others we won't mention. The event services are configured through different POE::Kernel methods, such as select_read(), delay(), and sig().

POE::Kernel tracks the associations between resources that generate events and the tasks that own them. It can do this because it keeps track of which task is active whenever an event is dispatched. It therefore knows which task has called its methods to allocate each resource. This all happens automatically.

POE::Kernel also knows when tasks should be destroyed. It detects when tasks have no more events to handle, and it knows when all their event generating resources have been released. Such tasks have nothing left to trigger event handlers, and POE::Kernel automatically reaps them.

POE::Kernel stops after the last session stops, since otherwise it would be sitting around doing nothing.

About POE::Session

POE::Session instances are the tasks that POE::Kernel manages. They are loosely modeled after UNIX processes.

Each session has its own private storage space, called a heap. Anything stored in one session's heap is not easily accessible by another session.

Each session owns its own resources and handles its own events. Resources only generate events for the sessions that own them, and events are only dispatched to sessions for which they are intended.

For example, multiple sessions can set identical alarms, and each will receive the timed event it requested. All other sessions will remain blissfully unaware of what has happened outside themselves.

About event handlers

Event handlers are plain Perl functions. What makes them special is the parameters POE::Kernel passes to them when they're called.

POE::Kernel passes parameters the usual way, through @_. The first seven members of this array define the session context in which the event is being delivered. They include

The remaining members of @_ are arguments of the event itself. What they contain depends upon the type of event being dispatched. I/O events, for example, include two arguments:

POE does not require programmers to assign all these parameters for every event handler. That would be a lot of silly work, seeing as most of them often go unused. Rather, the POE::Session class exports constants for the offsets into @_ where each parameter lives.

This makes it very easy to pluck useful values out of the parameter list while ignoring unnecessary ones. They also allow POE::Session to change the order or number of parameters without breaking programs.

For example, KERNEL, HEAP, and ARG0 are references to the

They may be assigned directly out of @_.

my $kernel = $_[KERNEL];
my $heap   = $_[HEAP];
my $thingy = $_[ARG0];

They may be assigned all in one go using an array slice.

my ( $kernel, $heap, $thingy ) = @_[ KERNEL, HEAP, ARG0 ];

And, of course, $_[KERNEL], $_[HEAP], and $_[ARG0] may be used directly in the event handler. We usually avoid this for custom arguments since ARG0 means very little by itself.

In all three cases we have pretended that five or more unneeded parameters simply don't exist.

Casiano Rodríguez León