1POE::NFA(3)           User Contributed Perl Documentation          POE::NFA(3)
2
3
4

NAME

6       POE::NFA - an event-driven state machine (nondeterministic finite
7       automaton)
8

SYNOPSIS

10         use POE::Kernel;
11         use POE::NFA;
12         use POE::Wheel::ReadLine;
13
14         # Spawn an NFA and enter its initial state.
15         POE::NFA->spawn(
16           inline_states => {
17             initial => {
18               setup => \&setup_stuff,
19             },
20             state_login => {
21               on_entry => \&login_prompt,
22               on_input => \&save_login,
23             },
24             state_password => {
25               on_entry => \&password_prompt,
26               on_input => \&check_password,
27             },
28             state_cmd => {
29               on_entry => \&command_prompt,
30               on_input => \&handle_command,
31             },
32           },
33         )->goto_state(initial => "setup");
34
35         POE::Kernel->run();
36         exit;
37
38         sub setup_stuff {
39           $_[RUNSTATE]{io} = POE::Wheel::ReadLine->new(
40             InputEvent => 'on_input',
41           );
42           $_[MACHINE]->goto_state(state_login => "on_entry");
43         }
44
45         sub login_prompt { $_[RUNSTATE]{io}->get('Login: '); }
46
47         sub save_login {
48           $_[RUNSTATE]{login} = $_[ARG0];
49           $_[MACHINE]->goto_state(state_password => "on_entry");
50         }
51
52         sub password_prompt { $_[RUNSTATE]{io}->get('Password: '); }
53
54         sub check_password {
55           if ($_[RUNSTATE]{login} eq $_[ARG0]) {
56             $_[MACHINE]->goto_state(state_cmd => "on_entry");
57           }
58           else {
59             $_[MACHINE]->goto_state(state_login => "on_entry");
60           }
61         }
62
63         sub command_prompt { $_[RUNSTATE]{io}->get('Cmd: '); }
64
65         sub handle_command {
66           $_[RUNSTATE]{io}->put("  <<$_[ARG0]>>");
67           if ($_[ARG0] =~ /^(?:quit|stop|exit|halt|bye)$/i) {
68             $_[RUNSTATE]{io}->put('Bye!');
69             $_[MACHINE]->stop();
70           }
71           else {
72             $_[MACHINE]->goto_state(state_cmd => "on_entry");
73           }
74         }
75

DESCRIPTION

77       POE::NFA implements a different kind of POE session: A non-
78       deterministic finite automaton.  Let's break that down.
79
80       A finite automaton is a state machine with a bounded number of states
81       and transitions.  Technically, POE::NFA objects may modify themselves
82       at run time, so they aren't really "finite".  Run-time modification
83       isn't currently supported by the API, so plausible deniability is
84       maintained!
85
86       Deterministic state machines are ones where all possible transitions
87       are known at compile time.  POE::NFA is "non-deterministic" because
88       transitions may change based on run-time conditions.
89
90       But more simply, POE::NFA is like POE::Session but with banks of event
91       handlers that may be swapped according to the session's run-time state.
92       Consider the SYNOPSIS example, which has "on_entry" and "on_input"
93       handlers that do different things depending on the run-time state.
94       POE::Wheel::ReadLine throws "on_input", but different things happen
95       depending whether the session is in its "login", "password" or
96       "command" state.
97
98       POE::NFA borrows heavily from POE::Session, so this document will only
99       discuss the differences.  Please see POE::Session for things which are
100       similar.
101

PUBLIC METHODS

103       This document mainly focuses on the differences from POE::Session.
104
105   get_current_state
106       Each machine state has a name.  get_current_state() returns the name of
107       the machine's current state.  get_current_state() is mainly used to
108       retrieve the state of some other machine.  It's easier (and faster) to
109       use $_[STATE] in a machine's own event handlers.
110
111   get_runstate
112       get_runstate() returns the machine's current runstate.  Runstates are
113       equivalent to POE::Session HEAPs, so this method does pretty much the
114       same as POE::Session's get_heap().  It's easier (and faster) to use
115       $_[RUNSTATE] in a machine's own event handlers, however.
116
117   spawn STATE_NAME => HANDLERS_HASHREF[, ...]
118       spawn() is POE::NFA's constructor.  The name reflects the idea that new
119       state machines are spawned like threads or processes rather than
120       instantiated like objects.
121
122       The machine itself is defined as a list of state names and hashes that
123       map events to handlers within each state.
124
125         my %states = (
126           state_1 => {
127             event_1 => \&handler_1,
128             event_2 => \&handler_2,
129           },
130           state_2 => {
131             event_1 => \&handler_3,
132             event_2 => \&handler_4,
133           },
134         );
135
136       A single event may be handled by many states.  The proper handler will
137       be called depending on the machine's current state.  For example, if
138       "event_1" is dispatched while the machine is in "state_2", then
139       handler_3() will be called to handle the event.  The state -> event ->
140       handler map looks like this:
141
142         $machine{state_2}{event_1} = \&handler_3;
143
144       Instead of "inline_states", "object_states" or "package_states" may be
145       used. These map the events of a state to an object or package method
146       respectively.
147
148         object_states => {
149           state_1 => [
150             $object_1 => [qw(event_1 event_2)],
151           ],
152           state_2 => [
153             $object_2 => {
154               event_1 => method_1,
155               event_2 => method_2,
156             }
157           ]
158         }
159
160       In the example above, in the case of "event_1" coming in while the
161       machine is in "state_1", method "event_1" will be called on $object_1.
162       If the machine is in "state_2", method "method_1" will be called on
163       $object_2.
164
165       "package_states" is very similar, but instead of using an $object, you
166       pass in a "Package::Name"
167
168       The "runstate" parameter allows "RUNSTATE" to be initialized
169       differently at instantiation time. "RUNSTATE", like heaps, are usually
170       anonymous hashrefs, but "runstate" may set them to be array references
171       or even objects.
172
173   goto_state NEW_STATE[, ENTRY_EVENT[, EVENT_ARGS]]
174       goto_state() puts the machine into a new state.  If an ENTRY_EVENT is
175       specified, then that event will be dispatched after the machine enters
176       the new state.  EVENT_ARGS, if included, will be passed to the entry
177       event's handler via "ARG0..$#_".
178
179         # Switch to the next state.
180         $_[MACHINE]->goto_state( 'next_state' );
181
182         # Switch to the next state, and call a specific entry point.
183         $_[MACHINE]->goto_state( 'next_state', 'entry_event' );
184
185         # Switch to the next state; call an entry point with some values.
186         $_[MACHINE]->goto_state( 'next_state', 'entry_event', @parameters );
187
188   stop
189       stop() forces a machine to stop.  The machine will also stop gracefully
190       if it runs out of things to do, just like POE::Session.
191
192       stop() is heavy-handed.  It will force resources to be cleaned up.
193       However, circular references in the machine's "RUNSTATE" are not POE's
194       responsibility and may cause memory leaks.
195
196         $_[MACHINE]->stop();
197
198   call_state RETURN_EVENT, NEW_STATE[, ENTRY_EVENT[, EVENT_ARGS]]
199       call_state() is similar to goto_state(), but it pushes the current
200       state on a stack.  At some later point, a handler can call
201       return_state() to pop the call stack and return the machine to its old
202       state.  At that point, a "RETURN_EVENT" will be posted to notify the
203       old state of the return.
204
205         $machine->call_state( 'return_here', 'new_state', 'entry_event' );
206
207       As with goto_state(), "ENTRY_EVENT" is the event that will be emitted
208       once the machine enters its new state.  "ENTRY_ARGS" are parameters
209       passed to the "ENTRY_EVENT" handler via "ARG0..$#_".
210
211   return_state [RETURN_ARGS]
212       return_state() returns to the most recent state in which call_state()
213       was invoked.  If the preceding call_state() included a return event
214       then its handler will be invoked along with some optional
215       "RETURN_ARGS".  The "RETURN_ARGS" will be passed to the return handler
216       via "ARG0..$#_".
217
218         $_[MACHINE]->return_state( 'success', @success_values );
219
220   Methods that match POE::Session
221       The following methods behave identically to the ones in POE::Session.
222
223       ID
224       option
225       postback
226       callback
227
228   About new() and create()
229       POE::NFA's constructor is spawn(), not new() or create().
230

PREDEFINED EVENT FIELDS

232       POE::NFA's predefined event fields are the same as POE::Session's with
233       the following three exceptions.
234
235   MACHINE
236       "MACHINE" is equivalent to Session's "SESSION" field.  It holds a
237       reference to the current state machine, and is useful for calling its
238       methods.
239
240       See POE::Session's "SESSION" field for more information.
241
242         $_[MACHINE]->goto_state( $next_state, $next_state_entry_event );
243
244   RUNSTATE
245       "RUNSTATE" is equivalent to Session's "HEAP" field.  It holds an
246       anonymous hash reference which POE is guaranteed not to touch.  Data
247       stored in "RUNSTATE" will persist between handler invocations.
248
249   STATE
250       "STATE" contains the name of the machine's current state.  It is not
251       equivalent to anything from POE::Session.
252
253   EVENT
254       "EVENT" is equivalent to Session's "STATE" field.  It holds the name of
255       the event which invoked the current handler.  See POE::Session's
256       "STATE" field for more information.
257

PREDEFINED EVENT NAMES

259       POE::NFA defines four events of its own.  These events are used
260       internally and may not be overridden by application code.
261
262       See POE::Session's "PREDEFINED EVENT NAMES" section for more
263       information about other predefined events.
264
265       The events are: "poe_nfa_goto_state", "poe_nfa_push_state",
266       "poe_nfa_pop_state", "poe_nfa_stop".
267
268       Yes, all the internal events begin with "poe_nfa_".  More may be
269       forthcoming, but they will always begin the same way.  Therefore please
270       do not define events beginning with "poe_nfa_".
271

SEE ALSO

273       Many of POE::NFA's features are taken directly from POE::Session.
274       Please see POE::Session for more information.
275
276       The SEE ALSO section in POE contains a table of contents covering the
277       entire POE distribution.
278

BUGS

280       See POE::Session's documentation.
281
282       POE::NFA is not as feature-complete as POE::Session.  Your feedback is
283       appreciated.
284

AUTHORS & COPYRIGHTS

286       Please see POE for more information about authors and contributors.
287
288
289
290perl v5.12.1                      2010-04-03                       POE::NFA(3)
Impressum