Check out the tutorial and other learning resources and examples available for MacRuby.

17-18 Apr 2009 » Golden Gate Ruby Conference
San Francisco, CA, USA
Rich Presents MacRuby & HotCocoa
15-16 May 2009 » Ruby on OS X
Amsterdam, Holland, The Netherlands
Laurent & Rich Presenting MacRuby and Hotcocoa
27-29 Aug 2009 » Lone Star Ruby Conference
Austin, Texas, USA
Rich Gives a MacRuby & HotCocoa Tutorial
Blog Overview
Mac OS X 10.5.4 has just been released, addressing the latest Ruby security problems discovered by Apple’s product security team, and also fixing the getaddrinfo regression, that was introduced in 10.5.3 and breaking DRb.
Please enjoy and do not hesitate to contact us if you discover regressions, and we will try to fix them as soon as possible.
MacRuby trunk got a new build system, entirely written with Rake. We managed to replace the previous autotools-based build system with a 570 lines of code Rakefile (which can still be refactored). We didn’t really need autotools since MacRuby aims to be installed on only one platform: Mac OS X. Maintaining the autotools files were really difficult, and we are very glad to now have a pure-Ruby build script.
Building and installing MacRuby is now very simple:
$ rake
$ sudo rake install
This will build and install MacRuby in /Library/Frameworks/MacRuby.framework, executable symbolic links in /usr/local/bin (with a “mac” prefix, for example “macruby”), Xcode templates and sample code.
To see the list of all tasks;
$ rake -T
(in /Volumes/Data/src/MacRuby)
rake all # Build MacRuby and extensions
rake clean # Clean local and extension build files
rake clean:ext # Clean extension build files
rake clean:local # Clean local build files
rake config_h # Create config.h
rake default # Same as all
rake extensions # Build extensions
rake framework:info_plist # Create the plist file for the framework
rake framework:install # Install the framework
rake install # Same as framework:install
rake macruby # Same as macruby:build
rake macruby:build # Build MacRuby
rake macruby:dylib # Build dynamic libraries for MacRuby
rake macruby:static # Build static libraries for MacRuby
rake miniruby # Create miniruby
rake objects # Build known objects
rake rbconfig # Create config file
rake sample_test # Run the sample tests
rake test # Same as sample_test
Also, MacRuby trunk has a faster Objective-C dispatcher. Around 4 times faster that MacRuby 0.2 (and way faster than RubyCocoa). This was possible by fixing bugs in the dispatcher and also cache some of the runtime information.
Let’s consider the following Objective-C class.
$ cat dummy.m
#import <Foundation/Foundation.h>
@interface Dummy : NSObject
@end
@implementation Dummy
- (id)doSomething
{
return @"";
}
- (id)doSomethingWith:(id)value
{
return value;
}
@end
void Init_dummy (void) {}
We can build it as a Ruby extension.
$ gcc dummy.m -o dummy.bundle -framework Foundation -dynamiclib -fobjc-gc"
Then, test calling the methods. First, the doSomething method, which is a very simple case.
$ ruby start.rb ruby -v -r osx/foundation -I. -r dummy -e "include OSX; o = Dummy.new; 1_000_000.times { o.doSomething }"
ruby 1.8.6 (2008-03-03 patchlevel 114) [universal-darwin9.0]
5.295735
5.290816
5.28286
$ ../miniruby02 -v -I. -r dummy -e "o = Dummy.new; 1_000_000.times { o.doSomething }"
MacRuby version 0.2 (ruby 1.9.0 2008-06-03) [universal-darwin9.0]
2.977553
2.98855
2.984585
$ ../miniruby -v -I. -r dummy -e "o = Dummy.new; 1_000_000.times { o.doSomething }"
MacRuby version 0.3 (ruby 1.9.0 2008-06-03) [universal-darwin9.0]
0.639648
0.65196
0.644522
Then, the doSomethingWith: method, a bit more complicated because one argument is passed, so both RubyCocoa and MacRuby are using libffi to call it.
$ ruby -v -r osx/foundation -I. -r dummy -e "include OSX; o = Dummy.new; o2 = 'foo'; 1_000_000.times { o.doSomethingWith(o2) }"
ruby 1.8.6 (2008-03-03 patchlevel 114) [universal-darwin9.0]
13.981403
13.943761
13.936082
$ ../miniruby02 -v -I. -r dummy -e "o = Dummy.new; o2 = 'foo'; 1_000_000.times { o.doSomethingWith(o2) }"
MacRuby version 0.2 (ruby 1.9.0 2008-06-03) [universal-darwin9.0]
7.267144
7.210777
7.267988
$ ../miniruby -v -I. -r dummy -e "o = Dummy.new; o2 = 'foo'; 1_000_000.times { o.doSomethingWith(o2) }"
MacRuby version 0.3 (ruby 1.9.0 2008-06-03) [universal-darwin9.0]
1.239323
1.259157
1.246987
These are very premature results, we expect to continue reducing the time spent in the dispatcher, in the near future, and hopefully to make it twice faster.
On a side note, Konrad M. Lawson was kind enough to generate a very nice screencast of MacRuby demonstrating the Xcode/IB integration. Thanks Konrad!
After 3 months of development, here comes the second release of MacRuby, 0.2! Check it out while it’s hot!
This is an important release which addresses many bugs but also re-implements parts of the runtime using the CoreFoundation framework.
In MacRuby 0.2, all strings, arrays and hashes are now native Cocoa types, represented by NSString, NSArray and NSDictionary objects, respectively.
The entire String, Array and Hash interface was rewritten on top of the Cocoa equivalents using the powerful CoreFoundation framework.
The previous implementation, inherited from MRI, is not used anymore. The rationale behind this change is simple:
It is no longer necessary to convert Ruby primitive types to Cocoa or vice-versa. For example, a String created in MacRuby can be passed as is, without conversion, to an underlying C or Objective-C API that expects an NSString. Similarly, any method of the Ruby String class can be performed on an NSString that comes from Objective-C.
Interestingly, the CoreFoundation implementation that MacRuby now uses has proven itself to be stable and performs quite well, even this early in the implementation process.
We did not work on any performance improvements for MacRuby 0.2 (we will address performance in the next upcoming release), but we noticed some dramatic performance gains in some areas nonetheless.
Inserting elements in an array is faster in MacRuby than the original 1.9 implementation, for example, mostly because CFArray switches on the fly its data structure to an implementation that performs well according to the current number of elements.
a=[]; 100_000.times { |i| a.insert(0, i) }
MacRuby version 0.2 (ruby 1.9.0 2008-06-03) [universal-darwin9.0]
0.326057
0.318714
0.314731
ruby 1.9.0 (2008-06-03 revision 16762) [i686-darwin9.0.0]
4.308484
4.382623
4.36368
ruby 1.8.6 (2008-03-03 patchlevel 114) [universal-darwin9.0]
4.608796
4.595334
4.581045
Regarding hashes, searching for a specific value (which isn’t something that is typically done) is shown to be faster.
h = Hash[*(1..10000).to_a]; 10000.times { |i| h.has_value?(i) }
MacRuby version 0.2 (ruby 1.9.0 2008-06-03) [universal-darwin9.0]
0.965304
0.955293
0.950316
ruby 1.9.0 (2008-06-03 revision 16762) [i686-darwin9.0.0]
3.790461
3.804271
3.815217
ruby 1.8.6 (2008-03-03 patchlevel 114) [universal-darwin9.0]
4.225632
4.225457
4.239244
And to finish with strings, it turns out that manipulations on multi-byte strings are faster in MacRuby than 1.9.
$ cat t3.rb
# -*- coding: utf-8 -*-
s = "わたしはロランです。" * 2000
s.length.times { |i| s[i] }
$ ruby b.rb t3.rb
MacRuby version 0.2 (ruby 1.9.0 2008-06-03) [universal-darwin9.0]
0.180019
0.180165
0.177425
ruby 1.9.0 (2008-06-03 revision 16762) [i686-darwin9.0.0]
1.624943
1.633502
1.62767
Speaking of strings, since every of them is now a CFString, they get for free features that weren’t present in the original 1.9 implementation, such as ICU transformations for example:
$ cat t3.rb
puts "watashiha".transform('Latin-Hiragana') +
"lauren".transform('Latin-Katakana') +
"desu.".transform('Latin-Hiragana')
$ macruby -v t3.rb
MacRuby version 0.2 (ruby 1.9.0 2008-05-17) [universal-darwin9.0]
わたしはラウレンです。
MacRuby is still slower in many cases, including very important ones such as objects allocation and methods dispatch. There are also too many areas in String, Array and Hash where we perform much less well than we should.
We plan to address this in the next release (0.3) as well as many other things, so stay tuned!