home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2000 May
/
Chip_2000-05_cd1.bin
/
zkuste
/
Perl
/
ActivePerl-5.6.0.613.msi
/
䆊䌷䈹䈙䏵-䞅䞆䞀㡆䞃䄦䠥
/
_5dd1cd1f75577f1f4747baf638935ae9
< prev
next >
Wrap
Text File
|
2000-03-23
|
23KB
|
497 lines
<HTML>
<HEAD>
<TITLE>POE::Session - POE State Machine</TITLE>
<LINK REL="stylesheet" HREF="../../../Active.css" TYPE="text/css">
<LINK REV="made" HREF="mailto:">
</HEAD>
<BODY>
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
<TR><TD CLASS=block VALIGN=MIDDLE WIDTH=100% BGCOLOR="#cccccc">
<STRONG><P CLASS=block> POE::Session - POE State Machine</P></STRONG>
</TD></TR>
</TABLE>
<A NAME="__index__"></A>
<!-- INDEX BEGIN -->
<UL>
<LI><A HREF="#name">NAME</A></LI><LI><A HREF="#supportedplatforms">SUPPORTED PLATFORMS</A></LI>
<LI><A HREF="#synopsis">SYNOPSIS</A></LI>
<LI><A HREF="#description">DESCRIPTION</A></LI>
<LI><A HREF="#exported constants">EXPORTED CONSTANTS</A></LI>
<LI><A HREF="#public methods">PUBLIC METHODS</A></LI>
<LI><A HREF="#state parameters">STATE PARAMETERS</A></LI>
<LI><A HREF="#custom events and parameters">CUSTOM EVENTS AND PARAMETERS</A></LI>
<LI><A HREF="#predefined events and parameters">PREDEFINED EVENTS AND PARAMETERS</A></LI>
<LI><A HREF="#about states' return values">ABOUT STATES' RETURN VALUES</A></LI>
<LI><A HREF="#see also">SEE ALSO</A></LI>
<LI><A HREF="#bugs">BUGS</A></LI>
<LI><A HREF="#authors & copyrights">AUTHORS & COPYRIGHTS</A></LI>
</UL>
<!-- INDEX END -->
<HR>
<P>
<H1><A NAME="name">NAME</A></H1>
<P>POE::Session - POE State Machine</P>
<P>
<HR>
<H1><A NAME="supportedplatforms">SUPPORTED PLATFORMS</A></H1>
<UL>
<LI>Linux</LI>
<LI>Solaris</LI>
<LI>Windows</LI>
</UL>
<HR>
<H1><A NAME="synopsis">SYNOPSIS</A></H1>
<PRE>
# Original inline session constructor:
new POE::Session(
name1 => \&name1_handler, # \&name1_handler is the "name1" state
name2 => sub { ... }, # anonymous is the "name2" state
\@start_args, # ARG0..ARGn for the the _start state
);</PRE>
<PRE>
# Original package session constructor:
new POE::Session(
$package, [ 'name1', # $package->name1() is the "name1" state
'name2', # $package->name2() is the "name2" state
],
\@start_args, # ARG0..ARGn for the start _start state
);</PRE>
<PRE>
# Original object session constructor:
my $object1 = new SomeObject(...);
my $object2 = new SomeOtherObject(...);
new POE::Session(
# $object1->name1() is the "name1" state
# $object1->name2() is the "name2" state
$object1 => [ 'name1', 'name2' ],
# $object2->name1() is the "name3" state
# $object2->name2() is the "name3" state
$object2 => [ 'name3', 'name4' ],
\@start_args, # ARG0..ARGn for the _start state
);</PRE>
<PRE>
# New constructor:
create POE::Session(
# ARG0..ARGn for the session's _start handler
args => \@args,
inline_states => { state1 => \&handler1,
state2 => \&handler2,
...
},
object_states => [ $objref1 => \@methods1,
$objref2 => { state_name_1 => 'method_name_1',
state_name_2 => 'method_name_2',
},
...
],
package_states => [ $package1 => \@function_names_1,
$package2 => { state_name_1 => 'method_name_1',
state_name_2 => 'method_name_2',
},
...
],
options => \%options,
);</PRE>
<PRE>
# Set or clear some session options:
$session->option( trace => 1, default => 1 );</PRE>
<P>
<HR>
<H1><A NAME="description">DESCRIPTION</A></H1>
<P>(Note: Session constructors were changed in version 0.06. Processes
no longer support multiple kernels. This made the $kernel parameter
to session constructors obsolete, so it was removed.)</P>
<P>POE::Session is a generic state machine class. Session instances are
driven by state transition events, dispatched by POE::Kernel.</P>
<P>Sessions are POE's basic, self-contained units of program execution.
They are equivalent to operating system processes or threads. As part
of their creation, sessions register themselves with the process'
Kernel instance. The kernel will keep track of their resources, and
perform garbage collection at appropriate times.</P>
<P>
<HR>
<H1><A NAME="exported constants">EXPORTED CONSTANTS</A></H1>
<P>POE::Session exports constants for states' parameters. The constants
are discussed down in the STATE PARAMETERS section.</P>
<P>
<HR>
<H1><A NAME="public methods">PUBLIC METHODS</A></H1>
<UL>
<LI>
new
<P>POE::Session::new() is the original, highly overloaded constructor
style. It creates a new POE::Session instance, populated with states
given as its parameters.</P>
<P>A reference to the new session will be given to the process' Kernel
instance. The kernel will manage the session and its resources, and
it expects perl to destroy the session when it releases its reference.</P>
<P>The constructor will also return a reference to the new session. This
reference may be used directly, but keeping a copy of it will prevent
perl from garbage collecting the session when the kernel is done with
it. Some uses for the session reference include posting ``bootstrap''
events to the session or manipulating the session's options with its
<CODE>option()</CODE> method.</P>
<P>Some people consider the <CODE>new()</CODE> constructor awkward, or ``action at a
distance''. POE provides a semantically ``sweeter'' Kernel method,
POE::Kernel::session_create() for these people. Please note, however,
that session_create is depreciated as of version 0.06_09, since
POE::Session has become a proper object.</P>
<P>POE::Session::new() accepts pairs of parameters, with one exception.
The first parameter in the pair determines the pair's type. The pairs
may be used interchangeably:</P>
<P>Inline states are described by a scalar and a coderef. The scalar is
a string containing the state's name, which is also the name of the
event that will trigger the state. The coderef is the Perl subroutine
that will be called to handle the event.</P>
<PRE>
new POE::Session( event_name => \&state_handler );</PRE>
<P>Object states are described by an object reference and a reference to
an array of method names. The named methods will be invoked to handle
similarly named events.</P>
<PRE>
my $object = new Object;
new POE::Session( $object => [ qw(method1 method2 method3) ] );</PRE>
<P>Package states are described by a package name and a reference to an
array of subroutine names. The subroutines will handle events with
the same names. If two or more packages are listed in the
constructor, and the packages have matching subroutine names, then the
last one wins.</P>
<PRE>
new POE::Session( 'Package' => [ 'sub1', 'sub2', 'sub3' ] );</PRE>
<P>Sessions may use any combination of Inline, Object and Package states:</P>
<PRE>
my $object = new Object;
new POE::Session( event_name => \&state_handler,
$object => [ qw(method1 method2 method3) ],
'Package' => [ 'sub1', 'sub2', 'sub3' ]
);</PRE>
<P>There is one parameter that isn't part of a pair. It is a stand-alone
array reference. The contents of this arrayref are sent as arguments
to the session's <STRONG>_start</STRONG> state.</P>
<P></P>
<LI>
create
<P>POE::Session::create() is a new constructor style. It does not use
parameter overloading and DWIM to discern different session types. It
also supports the ability to set options in the constructor, unlike
POE::Session::new().</P>
<P>Please see the SYNOPSIS for <CODE>create()</CODE> usage.</P>
<P></P>
<LI>
option
<P>POE::Session::option() stores, fetches or removes a session's option.
Options are similar to environment variables.</P>
<P>The <CODE>option()</CODE> method's behavior changed in version 0.06_09. It now
supports fetching option values without changing or deleting the
option.</P>
<PRE>
$session->option( 'name1' ); # Fetches option 'name1'
$session->option( name2 => undef ); # Deletes option 'name2'
$session->option( name3 => 1, # Sets name3...
name4 => 2 # ... and name4.
);</PRE>
<P>Actually, <CODE>option()</CODE> always returns the values of the options its
passed. If more than one option is supplied in the parameters, then
<CODE>option()</CODE> returns a reference to a hash containing names and previous
values. If a single option is specified, then <CODE>option()</CODE> returns its
value as a scalar.</P>
<P>The <CODE>option()</CODE> method can only accept more than one option name while
storing or deleting. POE::Session::option() only changes the options
that are present as parameters. Unspecified options are left alone.</P>
<P>For example:</P>
<PRE>
$session->option( trace => 1, default => 0 );</PRE>
<P>Logical values may be sent as either 1, 0, 'on', 'off', 'yes', 'no',
'true' or 'false'. Stick with 1 and 0, though, because somebody
somewhere won't like the value translation and will request that it be
removed.</P>
<P>These are the options that POE currently uses internally. Others may
be added later.</P>
<UL>
<LI>
trace
<P>Accepts a logical true/false value. This option enables or disables a
trace of events as they're dispatched to states.</P>
<P></P>
<LI>
default
<P>Accepts a logical true/false value. When the ``default'' option is
enabled, POE will warn and confess about events that arrive but can't
be dispatched. Note: The ``default'' option will not do anything if the
session has a <STRONG>_default</STRONG> state, because then every event can be
dispatched.</P>
<P></P></UL>
<LI>
ID
<P>POE::Session::ID() returns this session's unique ID, as maintained by
POE::Kernel. It's a shortcut for $kernel->ID_session_to_id($session).</P>
<P></P></UL>
<P>
<HR>
<H1><A NAME="state parameters">STATE PARAMETERS</A></H1>
<P>State parameters changed in version 0.06. Before 0.06, inline
handlers received different parameters than object and package
handlers. The call signatures have been unified in version 0.06.
This breaks programs written with POE 0.05 or earlier. Thankfully,
there aren't many.</P>
<P>To prevent future breakage, POE::Session now exports constants for
parameters' offsets into @_. Programs that use the constants are
guaranteed not to break whenever states' call signatures change. Or,
if parameters are removed, programs will break at compile time rather
than mysteriously failing at runtime.</P>
<P>Parameters may be used discretely:</P>
<PRE>
$_[KERNEL]->yield('next_state');</PRE>
<P>If several parameters are needed multiple times, it may be easier (and
faster) to assign them to lexicals all at once with an array slice:</P>
<PRE>
my ($kernel, $operation, $errnum, $errstr) =
@_[KERNEL, ARG0, ARG1, ARG2];</PRE>
<P>The parameter constants are:</P>
<UL>
<LI>
OBJECT
<P>The value in $_[OBJECT] is dependent on how the state was defined. It
is undef for inline states. For object states, it contains a
reference to the object that owns the method being called. For
package states, it contains the name of the package the subroutine
exists in.</P>
<P></P>
<LI>
KERNEL
<P>$_[KERNEL] is a reference to the kernel that is managing this session.
It exists for times when $poe_kernel isn't available. $_[KERNEL] is
recommended over $poe_kernel in states. They may be different at some
point.</P>
<P></P>
<LI>
SESSION
<P>$_[SESSION] is a reference to the current POE session. It is included
mainly as a parameter to POE::Kernel methods, and for manipulating
session options.</P>
<P></P>
<LI>
HEAP
<P>$_[HEAP] is a reference to a hash set aside for each session to store
its global data. Information stored in the heap will be persistent
between states, for the life of the session.</P>
<P>POE will destroy the heap when its session stops, but it will not walk
the heap and make sure that circular references are broken.
Developers are expected to do any special heap cleanup in the
session's <STRONG>_stop</STRONG> state.</P>
<P>Support for using $_[HEAP] (formerly known as $me or $namespace) as an
alias for $_[SESSION] in Kernel method calls is depreciated, starting
in version 0.06. It will be removed after version 0.07.</P>
<P></P>
<LI>
STATE
<P>$_[STATE] is the name of the state being invoked. In most cases, this
will be the name of the event that caused this handler to be called.
In some cases though, most notably with <STRONG>_default</STRONG> and <STRONG>_signal</STRONG>,
the state being invoked may not match the event being dispatched.
(Predictably enough, it will be _default or _signal). You can find
out the original event name for <STRONG>_default</STRONG> (see the <STRONG>_default</STRONG>
event's description). The <STRONG>_signal</STRONG> event includes the signal name
that caused it to be posted.</P>
<P></P>
<LI>
SENDER
<P>$_[SENDER] is a reference to the session that sent the event. It is
suitable as a destination for responses. Please be careful about
deadlocks is using POE::Kernel::call() in both directions.</P>
<P></P>
<LI>
ARG0..ARG9
<P>@_[ARG0..ARG9] are the first ten elements of @args, as passed to the
POE::Kernel post(), call(), yield(), <A HREF="../../../lib/Pod/perlfunc.html#item_alarm"><CODE>alarm()</CODE></A> and <CODE>delay()</CODE> methods. If
more than ten items are needed, they may be referenced as
$_[ARG9+1..], but it would be more efficient to pass them all as an
array reference in $_[ARG0].</P>
<P>Another way to grab the arguments, no matter how many there are, is:</P>
<PRE>
my @args = @_[ARG0..$#_];</PRE>
<P></P></UL>
<P>
<HR>
<H1><A NAME="custom events and parameters">CUSTOM EVENTS AND PARAMETERS</A></H1>
<P>Events that aren't prefixed with leading underscores may have been
defined by the state machines themselves or by Wheel instances the
machines are using.</P>
<P>In almost all these cases, the event name should be mapped to a state
in the POE::Session constructor. Finding the event's source may be
more difficult. It could come from a Wheel in the same session, or
one of the &kernel calls. In the case of inter-session communication,
it may even come from outside the session.</P>
<P>
<HR>
<H1><A NAME="predefined events and parameters">PREDEFINED EVENTS AND PARAMETERS</A></H1>
<P>POE reserves some event names for internal and standard use. All its
predefined events begin with an underscore, and future ones will too.
It may be wise to avoid leading underscores in your own event names.</P>
<P>Every predefined event is accompanied by the standard OBJECT, KERNEL,
SESSION, HEAP, STATE and SENDER parameters.</P>
<UL>
<LI>
_start
<P>Sessions can't start running until the kernel knows they exist. After
the kernel registers a session, it sends a <STRONG>_start</STRONG> event to let it
know it's okay to begin. POE requires every state machine to have a
special <STRONG>_start</STRONG> state. Otherwise, how would they know when to
start?</P>
<P>SENDER contains a reference to the new session's parent session.</P>
<P>ARG0..ARG9 contain parameters as they were given to the session's
constructor. See POE::Session::new() and POE::Session::create() for
more information.</P>
<P></P>
<LI>
_stop
<P>Sessions receive <STRONG>_stop</STRONG> events when it is time for them to stop.
<STRONG>_stop</STRONG> is dispatched to sessions just before the kernel destroys
them. The <STRONG>_stop</STRONG> state commonly contains special destructor code,
possibly to clean up things that the kernel doesn't know about.</P>
<P>Sessions stop when they run out of pending state transition events and
don't hold resources to create new ones. Event-generating resources
include selects (filehandle monitors), child sessions, and aliases.</P>
<P>The kernel's <CODE>run()</CODE> method will return if all its sessions stop.</P>
<P>SENDER is the session that posted the <STRONG>_stop</STRONG> event. In the case of
resource starvation, this is the KERNEL.</P>
<P>ARG0..ARG9 are empty in the case of resource starvation.</P>
<P></P>
<LI>
_signal
<P>POE sets handlers for most of the signals in %SIG. The only
exceptions are things which might exist in %SIG but probably
shouldn't. POE will not register signal handlers for SIGRTMIN, for
example, because doing that breaks Perl on some HP-UX systems.</P>
<P>Signals are propagated to child sessions first. Since every session
is a descendent of the kernel, posting signals to the kernel
guarantees that every session receives them.</P>
<P>POE does not yet magically solve Perl's problems with signals.
Namely, perl tends to dump core if it keeps receiving signals. That
has a detrimental effect on programs that expect long uptimes.</P>
<P>There are a few kinds of signals. The kernel processes each kind
differently:</P>
<P>SIGPIPE causes a <STRONG>_signal</STRONG> event to be posted directly to the session
that is running when the signal was received. ARG0 contains the
signal name, as it appears in %SIG.</P>
<P>The handler for SIGCHLD and SIGCLD calls <A HREF="../../../lib/Pod/perlfunc.html#item_wait"><CODE>wait()</CODE></A> to acquire the dying
child's process ID and result code. If the child PID is valid, a
<STRONG>_signal</STRONG> event will be posted to all sessions. ARG0 will contain
CHLD regardless of the actual signal name. ARG1 contains the child
PID, and ARG2 contains the contents of $? just after the <A HREF="../../../lib/Pod/perlfunc.html#item_wait"><CODE>wait()</CODE></A> call.</P>
<P>All other signals cause a <STRONG>_signal</STRONG> event to be posted to all
sessions. ARG0 contains the signal name as it appears in %SIG.</P>
<P>SIGWINCH is ignored. Resizing an xterm causes a bunch of these,
quickly killing perl.</P>
<P></P>
<LI>
_garbage_collect
<P>The <STRONG>_garbage_collect</STRONG> event tells the kernel to check a session's
resources and stop it if none are left. It never is dispatched to a
session. This was added to delay garbage collection checking for new
sessions. This delayed garbage collection gives parent sessions a
chance to interact with their newly-created children.</P>
<P></P>
<LI>
_parent
<P>The <STRONG>_parent</STRONG> event lets child sessions know that they are about to
be orphaned and adopted. It tells each child session who their old
parent was and who their new parent is.</P>
<P>SENDER should always equal KERNEL. If not, the event was spoofed by
another session. ARG0 is the session's old parent; ARG1 is the
session's new one.</P>
<P></P>
<LI>
_child
<P>The <STRONG>_child</STRONG> event is sent to parent sessions when they acquire or
lose child sessions. <STRONG>_child</STRONG> is dispatched to parents after the
children receive <STRONG>_start</STRONG> or before they receive <STRONG>_stop</STRONG>.</P>
<P>SENDER should always equal KERNEL. If not, the event was spoofed by
another session.</P>
<P>ARG0 indicates what is happening to the child. It is 'gain' if the
session is a grandchild being given by a dying child. It is 'lose' if
the session is itself a dying child. It is 'create' if the child was
created by the current session.</P>
<P>ARG1 is a reference to the child session. It will still be valid,
even if the child is in its death throes.</P>
<P>ARG2 is only valid when ARG0 is 'create'. It contains the return
value of the child's <STRONG>_start</STRONG> state. See ABOUT STATES' RETURN VALUES
for more information about states' return values.</P>
<P></P>
<LI>
Select Events
<P>Select events are generated by POE::Kernel when selected file handles
become active. They have no default names.</P>
<P>ARG0 is the file handle that had activity.</P>
<P></P>
<LI>
_default
<P>The <STRONG>_default</STRONG> state is invoked whenever a session receives an event
for which it does not have a registered state. If the session doesn't
have a <STRONG>_default</STRONG> state, then the event will be discarded. If the
session's <STRONG>default</STRONG> option is true, then POE will carp and confess
about the discarded event.</P>
<P>ARG0 holds the original event's name. ARG1 holds a reference to the
original event's parameters.</P>
<P>If <STRONG>_default</STRONG> catches a <STRONG>_signal</STRONG> event, its return value will be
used to determine if the signal was handled. This may make some
programs difficult to stop. Please see the description for the
<STRONG>_signal</STRONG> event for more information.</P>
<P>The <STRONG>_default</STRONG> state can be used to catch misspelled events, but
$session-><CODE>option('default',1)</CODE> may be better.</P>
<P></P></UL>
<P>
<HR>
<H1><A NAME="about states' return values">ABOUT STATES' RETURN VALUES</A></H1>
<P>States are evaluated in a scalar context. States that must return
more than one value should return an arrayref instead.</P>
<P>Signal handlers tell POE whether or not a signal was handled by
returning a logical true or false value. See the description for the
<STRONG>_signal</STRONG> state for more information.</P>
<P>POE::Kernel::call() will return whatever a called state returns. See
the description of POE::Kernel::call() for more information.</P>
<P>If a state returns a reference to an object in the POE namespace (or
any namespace starting with POE::), then that reference is immediately
stringified. This is done to prevent ``blessing bleed'' (see the
Changes file) from interfering with POE's and Perl's garbage
collection. The code that checks for POE objects does not look inside
data passed by reference-- it's just there to catch accidents, like:</P>
<PRE>
sub _stop {
delete $_[HEAP]->{'readwrite wheel'};
# reference to the readwrite wheel is implicitly returned
}</PRE>
<P>That accidentally returns a reference to a POE::Wheel::ReadWrite
object. If the reference was not stringified, it would delay the
wheel's destruction until after the session stopped. The wheel would
try to remove its states from the nonexistent session, and the program
would crash.</P>
<P>
<HR>
<H1><A NAME="see also">SEE ALSO</A></H1>
<P>POE; POE::Kernel</P>
<P>
<HR>
<H1><A NAME="bugs">BUGS</A></H1>
<P>The documentation for POE::Session::create() is fairly nonexistent.</P>
<P>
<HR>
<H1><A NAME="authors & copyrights">AUTHORS & COPYRIGHTS</A></H1>
<P>Please see the POE manpage.</P>
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
<TR><TD CLASS=block VALIGN=MIDDLE WIDTH=100% BGCOLOR="#cccccc">
<STRONG><P CLASS=block> POE::Session - POE State Machine</P></STRONG>
</TD></TR>
</TABLE>
</BODY>
</HTML>