Ruby Cocoa Run Loop

Hello,

I’ve been inspired by reading:

http://www.rubycocoa.com/mastering-cocoa-with-ruby/1

But I don’t really want to have to build an application that’s a ruby
console.

I’d like to be able to fire up the NSApplication’s run loop from
within a new NSThread. My thinking is that if I do this from IRB, I
can then continue to use the original thread. I’ll have a proper
application run loop that’s able to respond to events, but I’ll also
be able to continue developing code live within irb. Obviously, I’ll
have to be very careful in interacting with the main application, but
I think it ought to be possible with:

performSelectorOnMainThread_withObject_waitUntilDone.

:slight_smile: I suspect I’m being naive in the extreme to even expect this to
work. But as an optimist, I thought I’d see what happened if I tried.
Here’s my code:

class ApplicationRunner < OSX::NSObject
def run
pool = OSX::NSAutoreleasePool.alloc.init
NSApplication.sharedApplication.run
pool.release
end
end

runner = ApplicationRunner.alloc.init
OSX::NSThread.detachNewThreadSelector_toTarget_withObject(:exit,
runner, nil)

And here’s some output from it:

Object 0x54df40 of class NSCFString autoreleased with no pool in
2007-01-03 23:30:42.207 irb[4904] *** _NSAutoreleaseNoPool():
place - just leaking
Object 0x54f7d0 of class NSCFString autoreleased with no pool in
place - just leaking
2007-01-03 23:30:42.210 irb[4904] *** _NSAutoreleaseNoPool():
Object 0x54f7b0 of class NSException autoreleased with no pool in
place - just leaking
2007-01-03 23:30:42.210 irb[4904] *** Uncaught exception:
<RBException_SystemExit> exit

Which isn’t too hopeful.

Is this just a silly idea? Can anyone suggest what I’m doing wrong
(no doubt, quite a lot of things), or a better approach to this?

Cheers,
Benjohn

On 1/3/07, Benjohn B. [email protected] wrote:

I’d like to be able to fire up the NSApplication’s run loop from
within a new NSThread.

I can’t comment on any Mac-specific code, but in my experience mixing
threading/event models rarely works. Things like select() get
confused.

Spooq:

On 1/3/07, Benjohn B. [email protected] wrote:

I’d like to be able to fire up the NSApplication’s run loop from
within a new NSThread.

I can’t comment on any Mac-specific code, but in my experience mixing
threading/event models rarely works. Things like select() get
confused.

I’ve realised two things.

First, I don’t know what’s going on - I’m reading the big Cocoa
Programming book by Scott Anguish et al, and it’s helping. There’s lots
about the cocoa / objective c run time interface at the back. I presume
this is how the Ruby Cocoa bridge works. Anyway, it’s interesting, and
perhaps it’ll help. I suspect that at least one problem is that the Ruby
interpreter is unlikely to be thread safe and re-entrant. Perhaps it is,
I don’t know.

Second, starting a thread is just one approach. What I’m after is a
minimal way of:

  • Getting the application loop going while also
  • Continuing to have IRB interaction.

So I’ll keep on working on that :slight_smile:

Cheers,
Benjohn

On 1/4/07, [email protected] [email protected] wrote:

First, I don’t know what’s going on - I’m reading the big Cocoa
Programming book by Scott Anguish et al, and it’s helping. There’s lots
about the cocoa / objective c run time interface at the back. I presume
this is how the Ruby Cocoa bridge works. Anyway, it’s interesting, and
perhaps it’ll help. I suspect that at least one problem is that the Ruby
interpreter is unlikely to be thread safe and re-entrant. Perhaps it is,
I don’t know.

There are just so many ways and places it could be breaking, I would
try not to get involved with any of them :stuck_out_tongue:

Second, starting a thread is just one approach. What I’m after is a
minimal way of:

  • Getting the application loop going while also
  • Continuing to have IRB interaction.

Perhaps you could invert the problem, and put a widget in your app
that allowed you to type in code and eval it? You could probably
emulate a terminal-style interface without much effort.

Spooq:

Perhaps you could invert the problem, and put a widget in your app
that allowed you to type in code and eval it? You could probably
emulate a terminal-style interface without much effort.

It’s a good plan and I definitely could do that. In fact, the original
inspiration to do this came from an article that followed your
suggestion. I don’t want to do that however because it seems
restrictive.

My way round, I can have a re-usable component that you can “require”,
that will give you an application run loop. If you happen to be using it
from IRB, you can continue to explore and poke about with the
application. You could also fire it up from a script, or have your unit
tests making use of it.

The other way round (your inverted suggestion), I’ve got a basic
application that includes a console. Unfortunately, I loose the tools
I’m used to having available from a terminal prompt, and I think it
would restrict using it from a finished script or from a unit test, etc.

I’m sure there’s more to it than that, but I can’t put my finger on it.
Or I’m just being stubborn :slight_smile:

Cheers,
Benjohn

On Jan 4, 2007, at 5:09 AM, [email protected] wrote:

The other way round (your inverted suggestion), I’ve got a basic
application that includes a console. Unfortunately, I loose the tools
I’m used to having available from a terminal prompt, and I think it
would restrict using it from a finished script or from a unit test,
etc.

This is just a wild guess, but I wonder whether you could use the
iTerm framework (http://sourceforge.net/projects/iterm/) to embed a
console in your app. I suppose (because I haven’t tried it) that you
could instantiate a console using Ruby. It wouldn’t really help in
IRB’ing your running Ruby app, but it might at least let you have a
real shell that you (or your users) would interact with, still inside
your app.

–John