After trying out MacRuby, the port of which directly runs on Objective C, i decided to try and convert some of my existing RubyCocoa projects over in order to take advantage of the speed boost and the simplified interface.
While the process was relatively straightforward, i have decided to reproduce it here so anyone else in my predicament can get their applications up and running in RubyCocoa with the minimum of fuss.
Preamble

Firstly, open up the Project Info box by double clicking on your project in the tree.

Your project needs to use the 10.5 sdk, since that is the only version which MacRuby supports. If you are planning on targeting 10.4, then MacRuby is not for you.
In addition you need to make sure you enable the Garbage Collection for Objective C, otherwise the MacRuby framework won’t link. In case you have forgotten where this option is, go to the build tab, select “All Configurations” for the configuration, then look for “Objective-C Garbage Collection“.

I selected “Supported“, though you can use “Required” as well.
Spot the difference
While a MacRuby project is similar to a RubyCocoa one, there are a few differences. Obviously, they use different frameworks, the initialization in ruby is slightly different, and of course there are a few big differences in the interface.
1) main.m
RubyCocoa
#import <Cocoa/Cocoa.h>
#import <RubyCocoa/RBRuntime.h>
int main(int argc, const char *argv[])
{
return RBApplicationMain("rb_main.rb", argc, argv);
}
MacRuby
#import <MacRuby/MacRuby.h>
int main(int argc, char *argv[])
{
return macruby_main("rb_main.rb", argc, argv);
}
2) rb_main.rb
RubyCocoa
require 'osx/cocoa'
def rb_main_init
path = OSX::NSBundle.mainBundle.resourcePath.fileSystemRepresentation
rbfiles = Dir.entries(path).select {|x| /\.rb\z/ =~ x}
rbfiles -= [ File.basename(__FILE__) ]
rbfiles.each do |path|
require( File.basename(path) )
end
end
if $0 == __FILE__ then
rb_main_init
OSX.NSApplicationMain(0, nil)
end
MacRuby
framework 'Cocoa'
# Loading all the Ruby project files.
dir_path = NSBundle.mainBundle.resourcePath.fileSystemRepresentation
Dir.entries(dir_path).each do |path|
if path != File.basename(__FILE__) and path[-3..-1] == '.rb'
require(path)
end
end
# Starting the Cocoa main loop.
NSApplicationMain(0, nil)
3) Framework link
RubyCocoa

Located in /System/Library/Frameworks/RubyCocoa.framework
MacRuby

Located in /Library/Frameworks/MacRuby.framework
4) Generally speaking
Ignore the OSX module, use framework instead of require for frameworks, and don’t use ib_outlet or ib_action.
RubyCocoa
require 'osx/cocoa'
class MyClass < OSX::NSObject
ib_outlet :myOutlet
ib_action :myAction do |sender|
end
end
MacRuby
framework 'Cocoa'
class MyClass < NSObject
attr_writer :myOutlet
def myAction(sender)
end
end
In addition, since MacRuby is based on Ruby 1.9 (as opposed to 1.8.x) it would be a good idea to check for incompatibilities in your code which arise from changes in Ruby 1.9.
Celebrate
With any luck, provided you have followed the above and managed to convert all of your RubyCocoa code over, your app should now run with MacRuby!

Add New Comment
Thanks. Your comment is awaiting approval by a moderator.
Do you already have an account? Log in and claim this comment.
Add New Comment
Trackbacks
(Trackback URL)