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 call :
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 Ctrl+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 Ctrl+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.