Tim Burks
tim****@neont*****
Sat Aug 5 04:03:15 JST 2006
I recently posted an online article (http://www.rubycocoa.com/ mastering-cocoa-with-ruby) that contained a single-threaded RubyCocoa console. To get it to work, I resorted to a nasty hack: I wrote my own event loop that ran inside the console's readLine method. It would be very pretty (and an appealing feature of RubyCocoa) to be able to use continuations for this instead. The readLine method would be much simpler: def readLine app = OSX::NSApplication.sharedApplication @startOfInput = lengthOfTextView # in the original console, a replica of the main event handling loop was placed here # with continuations, we set the continuation here so that when it is called, we continue after the block # this is also where a console running in a separate thread would wait for input callcc do |@continuation| throw :IRB_CONTINUE end lineToReturn = currentLine @startOfInput = lengthOfTextView write("\n") return lineToReturn + "\n" end Then the textView_shouldChangeTextInRange_replacementString delegate could call the continuation whenever it detected a newline on input. But unfortunately it's not that simple. When I tested this, my application exited with "RBException_RuntimeError - continuation called across trap". Looking into it, I saw that each Objective-C call to Ruby is wrapped in a call to rb_protect so that Ruby exceptions can be caught. But this also sets a "cont_protect" variable that tracks the contexts in which a continuation is created and called, and these contexts must be the same for the call to be successful. Unfortunately, each rb_protect call sets cont_protect to a unique value. So it looks like we cannot use continuations created in one invocation from any other invocation. Has anyone tried to remove this limitation? Tim