On Thu, May 23, 2002 at 09:16:44PM -0400, Peter Chen wrote:
> I am working on a tutorial explaining how to poeize a procedural
> program, in the hope of making it easier for my coworkers to pick up
> POE.
>
> Since I have not worked with POE for that long, I am wondering whether
> there is an easier and more elegant way of doing this. This is what I
> have so far, starting with the most basic. I would appreciate your
> feedback.
>
>
> Given the following function foo:
>
> sub foo {
> &step1() or return (undef, 'step1 failed');
> &step2() or return (undef, 'step2 failed');
> &step3() or return (undef, 'step3 failed');
> &step4();
> }
>
> What's the easiest way to poeize this into the following form:
>
> $kernel->post($session, 'foo', $response_postback);
>
> Assume event foo, step1, ... step4 map to state poe_foo, poe_step1, ...
> poe_step4.
Depending on the application, I might do something like this.
sub poe_foo {
my ($kernel, $sender, $response, $cookie) = @_[KERNEL, SENDER, ARG0, ARG1];
my @steps = (\&step1, \&step2, \&step3, \&step4);
my @errors = ("step1 failed", "second step failed", "oops three",
"four was bad"
);
# The caller does not provide a cookie. Instead, one is generated
# from the first call. The cookie consists of two fields: the step
# number to execute, and a copy of the sender so an event can be
# posted back.
unless (defined $cookie) {
$kernel->refcount_increment($sender, "doing foo");
$cookie = [ 0, $sender ];
}
my ($step, $reply_to) = @$cookie;
# Execute the step. If it succeeds, and there are more steps, then
# post another "foo" with an updated cookie.
if ($steps[$step]->()) {
$step++;
if (defined $steps[$step]) {
$cookie->[0] = $step;
$kernel->yield("foo", $response, $cookie);
return;
}
# There are no more steps. Send back a positive response event.
$kernel->post($reply_to, $response, "success");
$kernel->refcount_decrement($reply_to, "doing foo");
return;
}
# The step failed. Send back an appropriate failure message.
$kernel->post($cookie->[1], $response, $errors[$step]);
$kernel->refcount_decrement($cookie->[1], "doing foo");
}
I think after writing about two of those, I'd go slightly mad and
create a function that built these for me. If it turned out that I
was doing this a lot, I would probably assume it's a generic pattern
and write a new type of Session to do it.
Here are a couple articles that discuss other porting issues,
specifically blocking syscalls like sleep(), and porting large loops
so they don't block POE as they run.
http://poe.perl.org/?POE_Cookbook/Waiting
http://poe.perl.org/?POE_Cookbook/Looping
-- Rocco Caputo / [EMAIL PROTECTED] / poe.perl.org / poe.sf.net