I have some follow-up thoughts, now that IO::Lambda has been rattling around in
my head for a few hours. Mostly it relates to how I'd try to explain it to
someone. Is this explanation correct:
A IO::Lambda object (a "lambda") is an FSM generator. The
lambda() function takes an initialization callback and returns a
lambda. When the lambda is executed, the FSM is created, the initialization
callback is executed to dynamically register event handlers and associated
callbacks and event processing begins.
Lambdas are executed using method calls to the lambda, such as
call(), wait(), etc. (as described elsewhere). (In what
circumstances would I want to use one method or another?) Arguments
to these execution methods are passed to the initialization callback
in @_ for dynamic configuration.
Within the initialization callback, special functions called
"predicates" register a callback in response to specific events. The
argument to a predicate function is the callback function itself.
The context() function is used prior to calling a predicate to
populate an argument stack for subsequent predicate calls. The argument
stack must match the argument signature of the predicate. (E.g. the
read() predicate requires a filehandle so context() must be
called with a filehandle argument before read() is called.)
Predicate callbacks may also call predicates, registering a new
event handler during the processing of an event. If context() is
not explictly called, the context that existed when the currently executing
callback was registered is used.
Some predicates may have side effects in addition to registering an
event callback. For example, the tail() predicate executes a lambda
(given in the context stack) and runs the callback provided when the
lambda finishes running.
That's my rough take on it. I think I'm being a little imprecise around
the definition of "predicate" as you seem to indicate that lambda()
is also a predicate. I remember enough of HOP to know why. In a way,
predicates just define conditions under which callbacks are to be run. The
lambda() function returns a lambda that can only be run explicitly
with a method call. The other predicates use the context to provide sugar
for automatically running the callback under certain conditions.
Also, explaining what gets returned from running a lambda really needs a
lot more explanation and some examples. Otherwise, I'd be tempted to use a
global to make sure each callback put its output in the right place so I
didn't have to worry about what happens inside the black box.
Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.