Piping with AnyEvent::Handle
Marc Lehmann
schmorp at schmorp.de
Tue Mar 15 12:04:38 CET 2011
On Mon, Mar 14, 2011 at 06:11:12PM +0100, yon ar c'hall <yon.ar.chall at gmail.com> wrote:
> However, if I move the line "my $aer; $aer = new AnyEvent::Handle fh => $r"
> just before the "AnyEvent->timer" creation, it's allright.
>
> So maybe what I'm trying to do is absolutely stupid, but if so, could
> someone please explain what's wrong whith it ?
Nothing stupid, I am afraid, you just have to think about lifetimes of
objects.
For blocking programming, reading, say, a line is simple:
my $line = readline $fh;
But for event based programming, the equivalent "readline" will return
instantly - so what keeps $fh alive, or more to the point, what makes sure
the operation actually is executed?
Most operations give you some kind of transaction object, in this case, it's
the handle itself. What you do here:
> my $aer; $aer = new AnyEvent::Handle fh => $r;
> $aer->push_read(line => sub {
> my (undef, $line) = @_;
> print "<$line>\n";
> });
means more or less, "create a handle" then "push a read request" and then
"destroy the handle", as perl automatically destroys variables that go out of
scope.
What you would have to do is keep your handle object around and destroy it
when finished, for example, when you want to just read that line, do this:
my $aer; $aer = new AnyEvent::Handle fh => $r;
$aer->push_read(line => sub {
my (undef, $line) = @_;
print "<$line>\n";
undef $aer; # keep $aer from being destructed until here
});
Now, if an error occurs, the object will be freed too, but you never get
told about it, so you should really also define an on_error callback.
Last not least, if all you ever want to do is read a line and nothing more,
then this solution is appropriate. however, if there is more than one line in
the pipe, then the handle object will read all of them (it can't know how
long the line is in advance and reads as much as it can), and destroying the
handle object will also destroy all data read so far.
So in general, once you created your handle object, it should become *the
handle*, i.e. you should not keep the original fh around.
--
The choice of a Deliantra, the free code+content MORPG
-----==- _GNU_ http://www.deliantra.net
----==-- _ generation
---==---(_)__ __ ____ __ Marc Lehmann
--==---/ / _ \/ // /\ \/ / schmorp at schmorp.de
-=====/_/_//_/\_,_/ /_/\_\
More information about the anyevent
mailing list