AnyEvent
view release on metacpan or search on metacpan
lib/AnyEvent/Intro.pod view on Meta::CPAN
of fear of severly limiting the usefulness of the module: If your module
requires Glib, it will not run in a Tk program.
L<AnyEvent> solves this dilemma, by B<not> forcing module authors to
either:
=over 4
=item - write their own event loop (because it guarantees the availability
of an event loop everywhere - even on windows with no extra modules
installed).
=item - choose one specific event loop (because AnyEvent works with most
event loops available for Perl).
=back
If the module author uses L<AnyEvent> for all his (or her) event needs
(IO events, timers, signals, ...) then all other modules can just use
his module and don't have to choose an event loop or adapt to his event
loop. The choice of the event loop is ultimately made by the program
author who uses all the modules and writes the main program. And even
there he doesn't have to choose, he can just let L<AnyEvent> choose the
most efficient event loop available on the system.
Read more about this in the main documentation of the L<AnyEvent> module.
=head1 Introduction to Event-Based Programming
So what exactly is programming using events? It quite simply means that
instead of your code actively waiting for something, such as the user
entering something on STDIN:
$| = 1; print "enter your name> ";
my $name = <STDIN>;
You instead tell your event framework to notify you in the event of some
data being available on STDIN, by using a callback mechanism:
use AnyEvent;
$| = 1; print "enter your name> ";
my $name;
my $wait_for_input = AnyEvent->io (
fh => \*STDIN, # which file handle to check
poll => "r", # which event to wait for ("r"ead data)
cb => sub { # what callback to execute
$name = <STDIN>; # read it
}
);
# do something else here
Looks more complicated, and surely is, but the advantage of using events
is that your program can do something else instead of waiting for input
(side note: combining AnyEvent with a thread package such as Coro can
recoup much of the simplicity, effectively getting the best of two
worlds).
Waiting as done in the first example is also called "blocking" the process
because you "block"/keep your process from executing anything else while
you do so.
The second example avoids blocking by only registering interest in a read
event, which is fast and doesn't block your process. The callback will
be called only when data is available and can be read without blocking.
The "interest" is represented by an object returned by C<< AnyEvent->io
>> called a "watcher" object - thus named because it "watches" your
file handle (or other event sources) for the event you are interested in.
In the example above, we create an I/O watcher by calling the C<<
AnyEvent->io >> method. A lack of further interest in some event is
expressed by simply forgetting about its watcher, for example by
C<undef>-ing the only variable it is stored in. AnyEvent will
automatically clean up the watcher if it is no longer used, much like
Perl closes your file handles if you no longer use them anywhere.
=head3 A short note on callbacks
A common issue that hits people is the problem of passing parameters
to callbacks. Programmers used to languages such as C or C++ are often
used to a style where one passes the address of a function (a function
reference) and some data value, e.g.:
sub callback {
my ($arg) = @_;
$arg->method;
}
my $arg = ...;
call_me_back_later \&callback, $arg;
This is clumsy, as the place where behaviour is specified (when the
callback is registered) is often far away from the place where behaviour
is implemented. It also doesn't use Perl syntax to invoke the code. There
is also an abstraction penalty to pay as one has to I<name> the callback,
which often is unnecessary and leads to nonsensical or duplicated names.
In Perl, one can specify behaviour much more directly by using
I<closures>. Closures are code blocks that take a reference to the
enclosing scope(s) when they are created. This means lexical variables
in scope when a closure is created can be used inside the closure:
my $arg = ...;
call_me_back_later sub { $arg->method };
Under most circumstances, closures are faster, use fewer resources and
result in much clearer code than the traditional approach. Faster,
because parameter passing and storing them in local variables in Perl
is relatively slow. Fewer resources, because closures take references
to existing variables without having to create new ones, and clearer
code because it is immediately obvious that the second example calls the
C<method> method when the callback is invoked.
( run in 1.309 second using v1.01-cache-2.11-cpan-39bf76dae61 )