From: Morton Goldberg Date: 2007-09-22T22:38:02+09:00 Subject: Re: Break loop by trapping INT On Sep 21, 2007, at 10:13 PM, 7stud -- wrote: > Morton Goldberg wrote: >> When the trap is triggered, the trap's proc object receives a 'call' >> message. This happens in the scope of top level, not in the scope of >> the while block. To get the result you want, you need to invoke a >> non- >> local jump mechanism. This can be done with catch and throw. >> >> trap('INT') { puts "done"; throw :quit } >> >> count = 0 >> catch :quit do >> while count < 10; >> puts count += 1 >> sleep 1 >> end >> end > > Yikes! Isn't that using catch/throw as a plain vanilla goto? Not quite. Catches have scope. Consider the following: trap('INT') { puts "done"; throw :quit } count = 0 catch :quit do while count < 10; catch :next do ; end puts count += 1 sleep 1 end end puts "But I don't want to quit!" throw :next That doesn't work because catch :next is invisible to throw :next. Throws only search upward in the stack frames, not downward. Now this could be made to work with continuations. With continuations you can do truly shocking things. But even if were just like a goto, so what? Using trap already injects non-local behavior into the script. A little catch and throw hardly matters afters that. And it gets the job done. In this particular case, because there is nothing to do after the while block, the OP could use: trap('INT') { puts "done"; exit } count = 0 while count < 10; puts count += 1 sleep 1 end But that's not really very different, only less general. Regards, Morton