MacRuby & HotCocoa

91
MacRuby & HotCocoa Tasty Apps for OS X Thilo Utke 2009

Transcript of MacRuby & HotCocoa

Page 1: MacRuby & HotCocoa

MacRuby & HotCocoaTasty Apps for OS X

Thilo Utke 2009

Page 2: MacRuby & HotCocoa

OverviewAbout - Web developer - macruby - - Upstream - Alex - Web developer - WebApplications - doningtext - forex-metal - In business for a while - bootstrap - Paper-C - fast - rails - ruby - reliable - testing - rspec - cucumber - ruby - reliable - macs - ruby - rails - text mate - fast - plugins - gems - tools - interesting techs - iphone - mac - tools - Objective-C - features like ruby - smalltalk - more code - Hello World Example - not so fast - unlike ruby - dropped it - heard about macruby 0.3 relase - on top of Obj-C - get curious - less code - on Mac - with Cocoa - major API - Desktop Applications - More like ruby - liked it - Its from Apple! - from - RubyWrapper for NSObject 2001 - Integration with ProjectBuilder (IB 2002) - 2006 Laurent Sansonetti - 10.5 shipped with OS X - 2008 MacRuby shall replace RubyCocoa - RubyCocoa is a scripting Bridge - Syntactic Sugar - Syntax Mismatch - 2 Object Graphs - Green Threads vs. native Threads - Ruby 1.8 and ObjectiveC - Standard Libs Broken - Slow!!! - Mismatch like String != NSString => more Code - Picture - Ruby first Class Citizen - MacRuby - Ruby 1.9 - Native Threads - Matches better with Obj Syntax - Faster - Tighter Integration with Obj-C - Share Base classes - Share Infrastructure - GC - MacRuby 0.5 - the best Ruby for Mac - In Development - NO GLI - Share IO - On top of LLVM - Doing optimizations - Calls Obj-C - class/methods/obj all Obj C - show Methods - No more libffi but uses a new C-dispatcher - Picture! - Show Mixing MacRuby with ObjC - Compiles Code JIT - soon AOT - other Platforms - iPhone? - IB integration! - Framework - main_rm - Outlet - Action - Delegates - Like ActiveRecord Callbacks - but fixed names - you tell who handle it - first responder - Delegate for Application - Show Random Number Gen with IB - Code Obj-C/MacRuby-

All the things I’d like to talk about.

Page 3: MacRuby & HotCocoa

OutlineIntro

Objective-C Encounter

Apple - Ruby

RubyCocoa

MacRuby 0.5

MacRuby <-> Obj-C

Interface Builder Integration

Back to Code with HotCocoa

Impact

Page 4: MacRuby & HotCocoa

I’m a WebDeveloper.

Page 5: MacRuby & HotCocoa

UPSTREAM

My Company

Page 6: MacRuby & HotCocoa

Alexander Lang, also Founder and Owner of Upstream

Page 7: MacRuby & HotCocoa

Wrote CouchPotato. Talks about Ruby Libs for CouchDB

Page 8: MacRuby & HotCocoa

We did Community, Productivity, Finance and Educational Websites. Our own product is doingText.com

Page 9: MacRuby & HotCocoa

Rails enabled us to build WebApps really fast.

Page 10: MacRuby & HotCocoa

Text

I love Ruby!

Page 11: MacRuby & HotCocoa

To be fast and deliver reliable applications, we build software with test first.

Page 12: MacRuby & HotCocoa

New libraries, gems and technics keep WebDevelopment interesting.

Page 13: MacRuby & HotCocoa

Boring!!!!

www.flickr.com/photos/ipom

Still I get bored easily, so I play with new technologies.

Page 14: MacRuby & HotCocoa

Thats why I have an iPhone.

Page 15: MacRuby & HotCocoa

That’s why Alex has an iPhone.

Page 16: MacRuby & HotCocoa

That’s why we play with couchDB.

Page 17: MacRuby & HotCocoa

That’s why I thought Obj-C might be interesting.

Page 18: MacRuby & HotCocoa

Obj-CRuby

SmallTalk

Ruby and Obj-C have a common ancestry.

Page 19: MacRuby & HotCocoa

Obj-CRuby

Reflective

Dynamic

Garbage Collection

Object Oriented

Characteristics they have in common.

Page 20: MacRuby & HotCocoa

Obj-CRuby

Closures

FFI, C-Ext C-SuperSet

methodname(1,2) method: 1 name:2

Interpreter Compiler

Things that differ.

Page 21: MacRuby & HotCocoa

Grabbed this book to start with Obj-C.

Page 22: MacRuby & HotCocoa

First Objective-C App@interface Foo : NSObject{ IBOutlet NSTextField *textField;}

- (IBAction)gerneate:(id)sender;- (IBAction)seed:(id)sender;@end

@impelemtation Foo

- (IBAction)generate:(id)sender{ int generated = (random() % 100) +1; [textField setIntValue:generated];}

- (IBAction)seed:(id)sender{ srandom(time(NULL)); [textField setStringValue:@"Generator seeded"];}

My first Obj-C code with header files, types, many braces and semicolons.

Page 23: MacRuby & HotCocoa

o_0Felt like back in C programming class. Thrown Obj-C away.Yes, Ruby spoiled me.

Page 24: MacRuby & HotCocoa

MacRuby 0.3

Heard about MacRuby with the 0.3 release.

Page 25: MacRuby & HotCocoa

First Objective-C Appclass Foo attr_writer :text_field def seed(sender) @text_field.StringValue = "Generator doesn't need to be seeded ;)" end def generate(sender) @text_field.StringValue = (rand(100) + 1) endend

Same Obj-C Tutorial App with MacRuby.

Page 26: MacRuby & HotCocoa

\0_0/Header files, types, braces, and semicolons are gone. Much less code. Yeah!

Page 27: MacRuby & HotCocoa

It is from Apple!

Page 28: MacRuby & HotCocoa

Apple wants Ruby to be a

first class citizen

on OS X

Where that comes from.

Page 29: MacRuby & HotCocoa

2001

Ruby extension for NSObject

and NSClassFromString function

by Hisakuni Fujimoto

Page 30: MacRuby & HotCocoa

2002

RubyCocoa Project

Ruby 1.6.7 on OS X 10.2

Page 31: MacRuby & HotCocoa

2005

Ruby 1.8.2 on OS X 10.4

For a long time nothing happened.

Page 32: MacRuby & HotCocoa

2006

Laurent Sansonetti from Apple joined RubyCocoa

Things started to move.

Page 33: MacRuby & HotCocoa

2007

Ruby 1.8.6, Rails, RubyGems

and RubyCocoa

on OSX 10.5

Big move

Page 34: MacRuby & HotCocoa

RubyCocoa

Obj-C Runtime

GCC

Obj-C

IO

Frameworks

GC

MRI 1.8

Ruby Code GC

Std LibApp

Bridge

RubyCocoa Architecture

Page 35: MacRuby & HotCocoa

RubyCocoa

Obj-C Runtime

GCC

Obj-C

IO

Frameworks

GC

MRI 1.8

Ruby Code GC

Std LibApp

Bridge

Use Objects from Obj-C in Ruby and vice versa

Syntax matching

[Class initWith:(type) p1 other:(type) p2]

Class.initWith_other(p1, p2)

Extending/Inheriting/Overwriting

Access to C-Structs

Page 36: MacRuby & HotCocoa

RubyCocoa

Obj-C Runtime

GCC

Obj-C

IO

Frameworks

GC

MRI 1.8

Ruby Code GC

Std LibApp

Bridge

Messaging between Obj-C and Ruby is slow!

Page 37: MacRuby & HotCocoa

RubyCocoa

Obj-C Runtime

GCC

Obj-C

IO

Frameworks

GC

MRI 1.8

Ruby Code GC

Std LibApp

Bridge

Two Object Spaces

"Hi" != @"Hi"

Green Threads vs. Native Threads

RubyCocoa can run only on the MainThread.Ruby needs patching to allow to work with the Obj-C runtime.

Page 38: MacRuby & HotCocoa

RubyCocoa

Obj-C Runtime

GCC

Obj-C

IO

Frameworks

GC

MRI 1.8

Ruby Code GC

Std LibApp

Bridge

Duplicated infrastructure

Page 39: MacRuby & HotCocoa

RubyCocoa

Obj-C Runtime

GCC

Obj-C

IO

Frameworks

GC

MRI 1.8

Ruby Code GC

Std LibApp

Bridge

Duplicated libraries

Ruby’s causing hang ups

Page 40: MacRuby & HotCocoa

Thanks to RubyCocoa for some cool apps, like GitNub.

Page 41: MacRuby & HotCocoa

2008

MacRuby

shall replace RubyCocoa

in the future

The appearance of MacRuby

Page 42: MacRuby & HotCocoa

2009

MacRuby gets popular

Ruby 1.8.7, Rails 2.3, RubyGems

and RubyCocoa

on OSX 10.6

Community starts to grow.Gets buzz, because it for example faster than YARV.Appears more in screencasts/conferences.

Apple Stayes true to ruby

Page 43: MacRuby & HotCocoa

MacRuby 0.5

Obj-C Runtime

GCC

LLVMJIT/AOT

Ruby Code

GC

Obj-C

Std LibApp

IO

Frameworks

MacRuby architecture

Page 44: MacRuby & HotCocoa

MacRuby 0.5

Obj-C Runtime

GCC

LLVMJIT/AOT

Ruby Code

GC

Obj-C

Std LibApp

IO

Frameworks

Object => NSObject

RubySpecific extensions

Same Primitives

Page 45: MacRuby & HotCocoa

./miniruby -e 'p Array.new.methods(true, true)'

[:"sortUsingFunction:context:", :"exchangeObjectAtIndex:withObjectAtIndex:", :removeAllObjects, :"getObjects:range:", :"containsObject:inRange:", :removeObjectsInRange, :removeObjectAtIndex, :removeLastObject, :"replaceObjectAtIndex:withObject:", :"insertObject:atIndex:", :addObject, :"countByEnumeratingWithState:objects:count:", :objectAtIndex, :count, :mutableCopyWithZone, :copyWithZone, :classForCoder, :finalize, :hash, :isEqual, :sortUsingDescriptors, :filterUsingPredicate, :initWithContentsOfURL, :initWithContentsOfFile, :sortUsingSelector, :"removeObjectsFromIndices:numIndices:", :removeObjectsAtIndexes, :"replaceObjectsAtIndexes:withObjects:", :"insertObjects:atIndexes:", :"sortUsingFunction:context:range:", :"initWithObjects:count:", :initWithCapacity, :removeObjectsInArray, :"removeObjectIdenticalTo:inRange:", :removeObjectIdenticalTo, :"removeObject:inRange:", :removeObject, :"removeObject:range:identical:", :setArray, :"setObject:atIndex:", :addObjectsFromArray, :"replaceObjectsI

With the extra second argument set on true, you can see the Obj-C methods.

Page 46: MacRuby & HotCocoa

MacRuby 0.5

Obj-C Runtime

LLVM

LLVMJIT/AOT

Ruby Code

GC

GCC

Std LibApp

IO

Frameworks

Generate Obj-C calls for Ruby code

Intermediate Representation (IR)

Optimization

JIT compiler to execute code

~ 3 x faster than YARV

AOT compiler very soon

LLVM = Low Level Virtual Machine

Page 47: MacRuby & HotCocoa

MacRuby 0.5

Obj-C Runtime

LLVM

LLVMJIT/AOT

Ruby Code

GC

GCC

Std LibApp

IO

Frameworks

Generate Obj-C calls for Ruby code

Intermediate Representation (IR)

Optimization

JIT compiler to execute code

~ 3 x faster than YARV

AOT compiler very soon

AOT Compiler might allow to build for the iPhone. The garbage collection is still an open question.

Page 48: MacRuby & HotCocoa

VM_DUMP_IR=1 ./miniruby -e 'p "Hello RailsWayCon!"'

"Hello RailsWayCon!"IR dump ----------------------------------------------; ModuleID = 'Roxor'

define i64 @0(i64 %self, i8* %sel) {MainBlock: %0 = tail call i64 (i8*, i64, i8*, i8*, i8, i32, ...)* @rb_vm_dispatch(i8* inttoptr (i64 4309091648 to i8*), i64 %self, i8* inttoptr (i64 4308940784 to i8*), i8* null, i8 0, i32 1, i64 34360384192) ; <i64> [#uses=1] ret i64 %0}

declare i64 @rb_vm_dispatch(i8*, i64, i8*, i8*, i8, i32, ...)------------------------------------------------------

How the IR in LLVM looks?

Page 49: MacRuby & HotCocoa

MacRuby 0.5

Obj-C Runtime

GCC

LLVMJIT/AOT

Ruby Code

GC

Obj-C

Std LibApp

IO

Frameworks

One runtime

One object space

Shared infrastructure

Multithreaded

No GIL is needed.

Page 50: MacRuby & HotCocoa

MacRuby 0.5

MacRuby is not fully functional yet.Not installable around 85% RubySpecs passes.You can play with miniruby.

Page 51: MacRuby & HotCocoa

MacRuby 0.4

“Stable” version

Page 52: MacRuby & HotCocoa

Using Frameworks#import <Cocoa/Cocoa.h>

framework 'Cocoa'  

Require a framework

Page 53: MacRuby & HotCocoa

Calling Obj-C Methods[dog makeNoise:@”wuff” level:6];

dog.makeNoise “wuff”, level:6

dog.makeNoise “wuff”, :level => 6  

Page 54: MacRuby & HotCocoa

Defining Methods for Obj-C- (id) makeNoise:(NSString)noise level:(NSInteger)level;

def makeNoise(noise, level:level) 

Page 55: MacRuby & HotCocoa

Using StructsNSPoint(0,1)

NSpoint.new(0,1) 

Page 56: MacRuby & HotCocoa

PointerNSError* error;

//MacRuby 0.4error = Pointer.new_with_type('@')

//MacRuby 0.5error = Pointer.new(:object)

 

Pointers are often used as a means for output parameters, mostly for error handling.

Page 57: MacRuby & HotCocoa

alloc & init

[[NSMutableArray alloc] init]

Array.alloc.init == Array.new

Array.alloc.initWithArray([1])==Array.arrayWithArray([1])

Page 58: MacRuby & HotCocoa

Use Ruby from Objective-C//Possibleid dog = [NSClassFromString(@"Dog") new];[dog bark]

//Saferid dog = [[MacRuby sharedRuntime] evaluateString:@"Dog.new"];[dog performRubySelector: @selector(bark:)];

Ruby Parameters are always objects, careful when passing primitives!

Page 59: MacRuby & HotCocoa
Page 60: MacRuby & HotCocoa

XCode

MacRuby is supported in XCode.

Page 61: MacRuby & HotCocoa

Interface Builder

Also support by Interface Builder

Page 62: MacRuby & HotCocoa

Read this book to learn more about Interface Builder and XCode.

Page 63: MacRuby & HotCocoa
Page 64: MacRuby & HotCocoa
Page 65: MacRuby & HotCocoa

Interface Builder

Wire the GUI to your code.

Page 66: MacRuby & HotCocoa

OUTLETS

References to GUI elements

Page 67: MacRuby & HotCocoa

attr_writer :stalutation

attr_accessor :user_input

Page 68: MacRuby & HotCocoa

ACTIONS

Methods, which are supposed to be called on UI events.

Page 69: MacRuby & HotCocoa

def showSalutation(sender) @stalutation.stringValue = "Hi RailsWayCon!" end

Page 70: MacRuby & HotCocoa

Delegates

Specific to Ruby Cocoa and other frameworks.

Page 71: MacRuby & HotCocoa

def applicationDidFinishLoading(message) // do somehting here end

I am your delegate

Answer my Emails!

Alternative explanation: ActiveRecord callbacks with fixed names defined in another object.

Page 72: MacRuby & HotCocoa

With InterfaceBuilder you get very much, very fast, with very little code but rather static.Good for small Apps, prototypes, App parts.

Page 73: MacRuby & HotCocoa

More control, understanding, flexibility.

Page 74: MacRuby & HotCocoa

Hello World MacRubyframework 'Cocoa'  app = NSApplication.sharedApplication window = NSWindow.alloc.initWithContentRect([0,0,200,60],   styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask ,  backing:NSBackingStoreBuffered,  defer:false) window.title = 'Hello World' label = NSTextField.alloc.initWithFrame(NSZeroRect)window.contentView.addSubview(label)label.stringValue = "Hello RailsWayCon!"label.setEditable(false)label.setSelectable(false)label.setBezeled(false)label.setDrawsBackground(false)label.sizeToFitlabel.frameOrigin = NSMakePoint((window.contentView.frameSize.width / 2) - (label.frameSize.width / 2)),   (window.contentView.frameSize.height / 3))window.displaywindow.orderFrontRegardless app.run

No InterfaceBuilder -> lots of code

Page 75: MacRuby & HotCocoa

by: http://www.flickr.com/photos/myphotourl

HotCocoa. Not only a tasty drink but a smart Lib shipped with MacRuby.

Page 76: MacRuby & HotCocoa

HotCocoa

Ruby Wrapper for major frameworks

AppKit

WebKit

QtKit

CoreGraphics

CoreImage

Page 77: MacRuby & HotCocoa

HotCocoa

Constructors with smart defaults

Constants mapped to Symbols

Custom methods

Easy delegation

Constructors- Building the instances of the mapped classes using the correct class-specific APIs Smart Defaults - Default constructor parameters to minimize the needed parametersConstant Mapping - Use of Ruby symbols to minimize the text and incr. readabilityCustom Methods- Ruby-friendly API for commonly used methodsDelegate Methods - Ruby-friendly methods for delegating instances

Page 78: MacRuby & HotCocoa

Hello World HotCocoarequire 'hotcocoa'include HotCocoa application do  window = window(title: 'Hello World', frame: [0,0,200,60])  label = label(text:'Hello RailsWayCon!', layout: {align::center})   window << labelend

Same App done with MacRuby.

Page 79: MacRuby & HotCocoa

\0_0/

Page 80: MacRuby & HotCocoa

Constructors with Smart Defaults

NSWindow.alloc.initWithContentRect([0,0,200,60], styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask ,  backing:NSBackingStoreBuffered,   defer:false)

window(title: 'Hello World', frame: [0,0,200,60]) 

Page 81: MacRuby & HotCocoa

Constant Mappings

button.setBezelStyle(NSRoundedBezelStyle)

button.bezel = :rounded  

Page 82: MacRuby & HotCocoa

Custom Methods

window.contentView.addSubview(label)

window << label  

Page 83: MacRuby & HotCocoa

Delegate

button.target = selfbutton.action = 'sayHello'def sayHello p 'Hello!'end

botton.on_action {p 'Hello!'} 

Page 84: MacRuby & HotCocoa

HotCoco Documentation

Soon

see /hotcocoa/mappings

HotConsole at gitHub to play arround

Page 85: MacRuby & HotCocoa

Lot of work to do to understand all available OS X frameworks.

Page 86: MacRuby & HotCocoa

So What?

The implications of MacRuby

Page 87: MacRuby & HotCocoa

Movement

?

Page 88: MacRuby & HotCocoa

Better Tool Support

!= Apple | XCode | InterfaceBuilder

HotCocoa, Rucola (App. Gen.)

HotConsole

Page 89: MacRuby & HotCocoa

Mature Testing Libraries

TestUnit (working)

Mocha (working)

Rspec

Shoulda

Cucumber (GUI manipulation?)

Page 90: MacRuby & HotCocoa

More applications for MAC!

Page 91: MacRuby & HotCocoa

Thanks

Start: macruby.org

Help: MacRuby-devel on MacOSForge

Twitter: @MacRuby

Thilo Utke 2009 for RailsWayConUpstream-Agile GmbH (upstream-berlin.com)