Skip to main content
A quick introduction to


                           MacRuby          Objective-C, Cocoa, LLVM, Grand Central
                                                       and other musings




Olivier Gutknecht - OSDC.fr - Oct. 3 2009
Olivier Gutknecht
olg@no-distance.net
twitter : olg




                                         MacRuby


  iCal, iSync, [...]     co-founder      Active lurker
                       Server Software
Breaking News !

MacRuby developer
attacked by raptors
Text
 Text
Text
 Text
MacRuby
Mac OS X Stack

  Applications


  Application
  Frameworks
                    Cocoa, WebKit, ...


Core Technologies   CoreGraphics, CoreFoundation, ...


     Darwin         Kernel, userland, libdispatch, ...
Ruby on OS X
2002   Mac OS X 10.2      Ruby 1.6.7

2005   Mac OS X 10.4      Ruby 1.8.2

2007   Mac OS X 10.5      Ruby 1.8.6
                       RubyCocoa, gems, Rails


2009   Mac OS X 10.6      Ruby 1.8.7
                       RubyCocoa, gems, Rails


20xx         ?          Sky is the limit
Ruby on OS X
• Ruby, just on another unix platform
• With some small improvements...
  e.g. mongrel_rails_persists on OS X Server
  launchd / bonjour integration


• What about Cocoa ?
Family business

         SmallTalk


Objective-C     Ruby
A “true” OS X App in
       Ruby ?




    Sure. Check out Gitnub
RubyCocoa
• A ruby-objc bridge
  (FUJIMOTO Hisakuni, 2001)
• Ruby 1.8
• Green threads, no reentrance
• Two runtimes, two GC
• ... interesting syntax
• Ouch
require 'osx/cocoa'; include OSX
app = NSApplication.sharedApplication
win = NSWindow.alloc.initWithContentRect_styleMask_backing_defer(
[0, 0, 200, 60], NSTitledWindowMask | NSClosableWindowMask |
NSMiniaturizableWindowMask | NSResizableWindowMask,
NSBackingStoreBuffered, false)
win.title = 'Hello World'
button = NSButton.alloc.initWithFrame(NSZeroRect)
win.contentView.addSubview(button)
button.bezelStyle = NSRoundedBezelStyle
button.title = 'Hello!'
button.sizeToFit
button.frameOrigin = NSMakePoint((win.contentView.frameSize.width/
2.0)-(button.frameSize.width/2.0), (win.contentView.frameSize.height/
2.0)-(button.frameSize.height/2.0))
button_controller = Object.new def button_controller.sayHello(sender)
puts "Hello OSDC!" end
button.target = button_controller
button.action = 'sayHello:'
win.display
win.orderFrontRegardless
app.run
Easy.
(when you’re proficient in Objective-C, Cocoa, Ruby and the bridge - here be dragons)
MacRuby
MacRuby

• One GC to release them all
MacRuby

• One GC to release them all
• One runtime to bind them
MacRuby

• One GC to release them all
• One runtime to bind them
• In the land of Cocoa where Obj-C lie
MacRuby
      Laurent Sansonetti
           (Apple)
          Vincent Isambart
            Kich Kilmer
             Eloy Duran
             Ben Stiglitz
           Matt Aimonetti
                  ...

       http://www.macruby.org
      http://twitter.com/macruby
Modest goals


• The best platform for Ruby developers
• A great platform for Cocoa developers
Bridge, what bridge ?
$ macirb
>> s = "osdc"
=> "osdc"

>> s.class
=> NSMutableString

>> s.class.ancestors
=> [NSMutableString, NSString, Comparable, NSObject, Kernel]

>> s.upcase
=> "OSDC"

>> s.uppercaseString
=> "OSDC"

>> s.respondsToSelector(:upcase)
=> 1

>> s.respond_to?(:upcase)
=> true
Bridge, what bridge ?

• A Ruby class is an Objective-C class
• A Ruby method is an Objective-C method
• A Ruby instance is an Objective-C instance
Syntax
                                             Objective-C
Person *person = [Person new];

[person name];
[person setName:name];
[person setFirstName:first lastName:last];


                                               MacRuby
person = Person.new

person.name
person.name = myName
person.setFirstName(first, lastName:last)
HotCocoa
require ‘hotcocoa’
include HotCocoa

application do
  win = window :title => ‘hello OSDC’, :frame => [0, 0, 200, 60]
  b = button :title => ‘Hello!’, :layout => {:align => :center}
  win << b
  b.on_action { puts “Hello OSDC!” }
end



       A thin layer by Rich Kilmer, providing a natural
         ruby experience when coding Cocoa apps
Ruby 1.9


Parser     Runtime   Built-in classes

YARV        GC           Stdlib
MacRuby

               Runtime
  Parser                      Stdlib

LLVM/Roxor     libobjc   Built-in Classes
AOT    JIT     libauto
                         CoreFoundation
MacRuby 0.4 - 04/09

•   XCode integration

•   Embedding / Runtime
    Control

•   HotCocoa

•   Threaded GC
MacRuby 0.5 - xx/09

•   YARV ? LLVM !

•   RubySpec

•   AOT

•   GrandCentral

•   ...
Why LLVM ?
Coolest Logo Ever
Everybody loves
 microbenchmarks
(lies, damn lies and benchmarks)



                            From a bench by Patrick Thomson @ C4
C

static int fib(int n)
{
  if (n < 3) {
    return 1;
  }
  else {
    return fib(n - 1) + fib(n - 2);
  }
}
Objective-C
@implementation Fib
- (int)fib:(int)n
{
  if (n < 3) {
     return 1;
  }
  else {
     return [self fib:n - 1] + [self fib:n - 2];
  }
}
@end
4




                     3
execution time (s)




                     2




                     1




                     0
                             fib(40)
                         C             Objective-C
Ruby

def fib(n)
  if n < 3
    1
  else
    fib(n-1) + fib(n-2)
  end
end

p fib(ARGV.join("").to_i)
4




                     3
execution time (s)




                     2




                     1




                     0
                               fib(40)


                         C   MacRuby     Objective-C
MRI Ruby 1.8
$ ruby fibo.rb 40
102334155


                               MacRuby
$ macruby fibo.rb 40
102334155


                           MacRuby AOT
$ macrubyc fibo.rb -o fibo
$ ./fibo 40
102334155
Grand Central
# A GCD-based implementation of the sleeping barber problem:
#   http://en.wikipedia.org/wiki/Sleeping_barber_problem
#   http://www.madebysofa.com/#blog/the_sleeping_barber

waiting_chairs = Dispatch::Queue.new('com.apple.waiting_chairs')
semaphore = Dispatch::Semaphore.new(3)
index = -1
while true
  index += 1
  success = semaphore.wait(Dispatch::TIME_NOW)
  if success != 0
    puts "Customer turned away #{index}"
    next
  end
  waiting_chairs.dispatch do
    semaphore.signal
    puts "Shave and a haircut #{index}"
  end
end
Tools Galore

    ?
Why MacRuby ?

• Ruby for “mac-like” desktop applications
• A wonderful experimentation playground
• ... Interesting perspectives
Q&A

• Ruby 1.9 compatibility
 • Right now, ≈ 80% on rubyspec
• Other platforms, portability
 • No closed-source dependancies, no
    definitive technical blocker
 • ... Any takers ?
Thanks!