Ruby - Procedure objects
| Ruby user's guide | Procedure objects | |
It is often desirable to be able to specify responses to unexpected
events. As it turns out, this is most easily done if we can pass
blocks of code as arguments to other methods, which means we want to
be able to treat code as if it were data.
A new procedure object is formed using proc
:
ruby> quux = proc {
| print "QUUXQUUXQUUX!!!\n"
| }
#<Proc:0x4017357c> |
Now what quux
refers to is an object, and like most
objects, it has behavior that can be evoked. Specifically, we
can ask it to execute, via its call
method:
ruby> quux.call
QUUXQUUXQUUX!!!
nil |
So, after all that, can quux
be used as a method
argument? Sure.
ruby> def run( p )
| print "About to call a procedure...\n"
| p.call
| print "There: finished.\n"
| end
nil
ruby> run quux
About to call a procedure...
QUUXQUUXQUUX!!!
There: finished.
nil |
The trap
method lets us assign the response of our choice
to any system signal.
ruby> inthandler = proc{ print "^C was pressed.\n" }
#<Proc:0x401730a4>
ruby> trap "SIGINT", inthandler
#<Proc:0x401735e0> |
Normally pressing ^C makes the interpreter quit. Now a
message is printed and the interpreter continues running, so you don't
lose the work you were doing. (You're not trapped in the
interpreter forever; you can still exit by typing exit
or
pressing ^D.)
A final note before we move on to other topics: it's not strictly
necessary to give a procedure object a name before binding it to a
signal. An equivalent anonymous procedure object would
look like
ruby> trap "SIGINT", proc{ print "^C was pressed.\n" }
nil |
or more compactly still,
ruby> trap "SIGINT", 'print "^C was pressed.\n"'
nil |
This abbreviated form provides some convenience and readability
when you write small anonymous procedures.