Date: | Mon, 23 Feb 2004 17:55:30 -0800 |
From: | Scott Walters <scott [...] illogics.org> |
To: | bug-POE [...] rt.cpan.org |
Subject: | feature request: Coro support |
Feature request: Coro support in POE. Coro would allow people to write more natural Perl,
using lexical variables to hold intermeidate values between invocations of the event
handler and it would allow them to nest logic in if statements, while statements, and so
on, building up a lexical context. Dorks from the functional world (like myself) prefer
this style to the small event handlers normally associated with POE code.
The toy finger client included with Coro is probably the best example I have of using Coro
with Event. Coro comes with a drop in Event replacement (or glue?), Coro::Event. Probably
glue come to think of it.
Coro is essentially a non-preemptive multithreading system. There are 3 precepts of coro:
Things in async { } blocks are run in the background as a new task. Routines marked
:Coro put the call into the background. loop() runs it all, or you can just cede()
if you don't want to wait until you'd otherwise block on IO. Actually coroutines are
more than just cooperative multithreading (a function is essentially its own
thread, and when it is called, it resumes whre it left off, and when it returns, it
doesn't stop executing but instead just transfers control back to its caller
with a return value), but for the purposes of POE, real coroutines don't matter.
use Coro;
use Coro::Event;
use Coro::Socket;
# this gets started everytime a user enters a finger command
sub finger {
my $user = shift;
my $host = shift;
my $fh = new Coro::Socket PeerHost => $host, PeerPort => "finger"
or die "$user\@$host: $!";
print $fh "$user\n";
print "$user\@$host: $_" while <$fh>;
print "$user\@$host: done\n";
}
my $stdin = new_from_fh Coro::Handle \*STDIN;
# this is the main task
sub keyboard : Coro {
$|=1;
while() {
print "cmd> "; my $cmd = <$stdin>; chomp $cmd;
if ($cmd eq "finger") {
print "user> "; my $user = <$stdin>; chomp $user;
print "host> "; my $host = <$stdin>; chomp $host;
async { finger($user, $host) };
} elsif ($cmd eq "quit") {
unloop(777);
terminate;
} else {
print "unknown command '$cmd', either 'finger' or 'quit'\n";
}
}
}
Thanks!
-scott/scrottie