Capítulo 19. Objetos procedimiento

A menudo es deseable tener la posibilidad de definir respuestas específicas a sucesos inesperados. Resulta que esto se consigue con gran sencillez si podemos pasar un bloque de código a otros métodos, lo que significa que deseamos tratar el código como si fuesen datos.

Un objeto procedimiento nuevo se obtiene utilizando proc:


ruby> quux = proc {
ruby|   print "QUUXQUUXQUUX!!!\n"
ruby| }
#<Proc:0x401c4884>

Ahora quux referencia a un objeto y como las mayoría de los objetos, tiene un comportamiento que se puede invocar. Concretamente, podemos pedir que se ejecute a través de su método call


ruby> quux.call
QUUXQUUXQUUX!!!
nil

Luego, después de todo esto. ¿Podemos utilizar quux cómo un argumento de un método? Ciertamente.


ruby> def run ( p )
ruby|   print "Vamos a llamar a un procedimiento ... \n"
ruby|   p.call
ruby|   print "Finalizado. \n"
ruby| end
nil
ruby> run quux
Vamos a llamar a un procedimiento ...
QUUXQUUXQUUX!!!
Finalizado.
nil

El método trap nos permite asignar una respuesta personalizada a cualquier señal del sistema.


ruby> inthandler = proc{ print "^C ha sido pulsado.\n" }
#<Proc:0x401c4104>
ruby> trap "SIGINT", inthandler
nil

Normalmente, al pulsar ^C se sale del intérprete. Ahora se imprime un mensaje y el intérprete sigue ejecutándose, así no se pierde el trabajo realizado. (No nos encontramos atrapados en el intérprete para siempre; todavía se puede salir tecleando exit o pulsando ^D.)

Una observación final antes de pasar a otros temas: no es necesario dar al objeto procedimiento un nombre antes de asociarlo a una señal. Un objeto procedimiento anónimo equivalente se asemejaría a:


ruby> trap "SIGINT", proc{ print "^C ha sido pulsado.\n" }
#<Proc:0x401c4104>

O de una forma más compacta todavía,


ruby> trap "SIGINT", 'print "^C ha sido pulsado.\n"'
#<Proc:0x401c3d44>

Este formato abreviado es mas adecuado y legible cuando se escriben pequeños procedimientos anónimos.