Lo habitual cuando se llama a un constructor es guardar el objeto retornado por el constructor en una variable:
{ my $w = Event->signal( signal => 'INT', cb => sub { warn $_[0]->hits,"\n"; }); }
Cuando se usa Event es habitual ver código - como en el siguiente ejemplo - en el que no se almacena el objeto retornado:
1 use strict; 2 use warnings; 3 4 use Event; 5 Event->signal( 6 signal => 'INT', 7 cb => sub { 8 warn "Detected ",$_[0]->hits," SIGINT events\n"; 9 warn "Sleeping now\n"; 10 11 Event::sleep(10); 12 warn "Slept.\n"; 13 } 14 ); 15 16 Event::loop;
En general un callback se ejecuta en exclusiva. Existe una excepción a la regla:
Si una señal llega mientras el callback esta ejecutando sleep o select
para esperar, el callback se verá interrumpido por la señal. Si se quiere un
sleep
no interrumpible deberemos usar Event::sleep .
Observe la siguiente variante del progframa anterior:
pp2@nereida:~/src/perl/Event$ cat -n sleepsignalwatcher.pl 1 use strict; 2 use warnings; 3 4 use Event; 5 6 my $count = 0; 7 Event->signal( 8 signal => 'INT', 9 cb => sub { 10 warn "Detected ",$_[0]->hits," SIGINT events\n"; 11 $count += $_[0]->hits; 12 warn "Sleeping now\n"; 13 14 sleep(10); 15 16 Event::unloop if $count > 5; 17 warn "Slept.\n"; 18 } 19 ); 20 21 Event::loop;
Cuando se ejecutan los códigos anteriores se producen salidas como estas:
Con Event::sleep |
Con sleep |
pp2@nereida:~/src/perl/Event$ perl signalwatcher.pl Detected 1 SIGINT events Sleeping now Slept. Detected 17 SIGINT events Sleeping now Slept. |
pp2@nereida:~/src/perl/Event$ perl sleepsignalwatcher.pl Detected 1 SIGINT events Sleeping now Slept. Detected 1 SIGINT events Sleeping now Slept. Detected 1 SIGINT events Sleeping now Slept. Detected 1 SIGINT events Sleeping now Slept. Detected 1 SIGINT events Sleeping now Slept. Detected 1 SIGINT events Sleeping now Slept. pp2@nereida:~/src/perl/Event$ |
La gestión que hace Event de los watchers resulta en un aumento del contador de referencias de manera que el objeto watcher no es destruido al finalizar el ámbito:
{ Event->signal( signal => 'INT', cb => sub { warn $_[0]->hits,"\n"; }); }
El nuevo vigilante permanece después de abandonado el
ámbito léxico. ¿Cómo accederlo entonces?. La respuesta es que se
dispone de los siguientes métodos de la clase Event
para
obtener los watchers:
all_watchers |
Lista de los watchers registrados |
all_running |
Lista de los watchers con callbacks en ejecución |
all_idle |
Lista de los watchers ociosos, listos para ser servidos pero retrasados por eventos mas priorizados |
Además el objeto evento pasado al callback dispone de un método w
que permite acceder al watcher que le detectó.
Así pues una construcción típica
en Event
es:
sub callback { my $event = shift; my $watcher = $event->w; ... }