Lately, I’ve been having fun with RubyCocoa while reading Brian Marick‘s RubyCocoa. It’s an entertaining book, and I really like RubyCocoa itself. But I hit a little gotcha. Take the following code:

PathController.rb

1 require osx/cocoa
2
3 class PathController < OSX::NSObject
4 ib_outlet :path, :events
5 ib_action :choosePath
6
7 def choosePath(sender)
8 panel = OSX::NSOpenPanel.openPanel
9 panel.canChooseFiles = false
10 panel.canChooseDirectories = true
11 panel.allowsMultipleSelection = false
12
13 result = panel.runModal
14 if result == OSX::NSFileHandlingPanelOKButton then
15 self.path.title = panel.filename
16 end
17 end
18 end

What could be wrong with this? Turns out #ib_oulet does not define accessors for the instance variables it defines. Look at the exception:


1 OSX::OCMessageSendException: Can’t get Objective-C method signature for selector ‘events’ of receiver #<PathController:0×2297be class=‘PathController’ id=0×534ec0>
2 /Library/Frameworks/RubyCocoa.framework/Resources/ruby/osx/objc/oc_wrapper.rb:50:in `ocm_send’
3 /Library/Frameworks/RubyCocoa.framework/Resources/ruby/osx/objc/oc_wrapper.rb:50:in `method_missing’
4 /Users/francois/Projects/fsevtest/build/Debug/fsevtest.app/Contents/Resources/PathController.rb:27:in `choosePath’
5 /Users/francois/Projects/fsevtest/build/Debug/fsevtest.app/Contents/Resources/rb_main.rb:22:in `NSApplicationMain’
6 /Users/francois/Projects/fsevtest/build/Debug/fsevtest.app/Contents/Resources/rb_main.rb:22
7 /Library/Frameworks/RubyCocoa.framework/Resources/ruby/osx/objc/oc_wrapper.rb:50:in `ocm_send’: Can’t get Objective-C method signature for selector ‘events’ of receiver #<PathController:0×2297be class=‘PathController’ id=0×534ec0> (OSX::OCMessageSendException)
8 from /Library/Frameworks/RubyCocoa.framework/Resources/ruby/osx/objc/oc_wrapper.rb:50:in `method_missing’
9 from /Users/francois/Projects/fsevtest/build/Debug/fsevtest.app/Contents/Resources/PathController.rb:27:in `choosePath’
10 from /Users/francois/Projects/fsevtest/build/Debug/fsevtest.app/Contents/Resources/rb_main.rb:22:in `NSApplicationMain’
11 from /Users/francois/Projects/fsevtest/build/Debug/fsevtest.app/Contents/Resources/rb_main.rb:22

From the obscure message, I gathered this was some kind of NoMethodError (why couldn’t they use an exception with a good name?) That was Sunday morning. Sunday evening, I suddenly had a flash that ib_outlet wouldn’t define an accessor. Changed my code to use the instance variable instead:

PathController.rb

1 if result == OSX::NSFileHandlingPanelOKButton then
2 @path.title = panel.filename
3 end

Lo and behold! It worked beautifully.

Search

Your Host

A picture of me

I am François Beausoleil, a Ruby on Rails and Scala developer. During the day, I work on Seevibes, a platform to measure social interactions related to TV shows. At night, I am interested many things. Read my biography.

Top Tags

Books I read and recommend

Links

Projects I work on

Projects I worked on