The simplest POE program consists of two modules and some custom code: POE::Kernel, POE::Session, and the event handlers that use them.
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.
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.
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
heap
,
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
heap
, and
@_
.
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.