Slide 1

Slide 1 text

Differences CRuby/MacRuby/RubyMotion twitter: @watson1978

Slide 2

Slide 2 text

自己紹介 • MacRubyのコミッターしています • コミットが1000回を超えました!

Slide 3

Slide 3 text

アジェンダ • MacRuby/RubyMotionの系譜 • CRuby vs MacRuby • MacRuby vs RubyMotion

Slide 4

Slide 4 text

MacRuby RubyMotionの系譜

Slide 5

Slide 5 text

系譜 CRuby MacRuby RubyMotion 2008/02 2011/11 1.9.0 p1 2008/03 v0.11 2011/11 v1.0 2012/05

Slide 6

Slide 6 text

CRuby vs MacRuby

Slide 7

Slide 7 text

CRuby1.9の構成 アプリケーション YARV 鬼車 組込みライブラリ GVL Ruby VM GC 添付ライブラリ ライブラリ OS

Slide 8

Slide 8 text

MacRubyの構成 アプリケーション YARV LLVM 鬼車 ICU 組込みライブラリ GVL Ruby VM GC libauto 添付ライブラリ Foundation / ライブラリ MacOSX GCDなど

Slide 9

Slide 9 text

MacRubyとCRubyの違い • GVLを廃止 → 各スレッドが並列動作可能 • GC → libauto • (RubyCocoaでRubyとMacOSXのGCの動作がコン フリクトし、クラッシュしたり・・・) • キーワード付き引数をサポート • ルートクラスObject → NSObject • Objective-Cの定数や構造体、GCDなどを扱 うために独自機能を追加

Slide 10

Slide 10 text

キーワード付き引数 - (void)init:(char*)name withPrice:(int)price { printf("%s %d", name, price); } ... [[Fruit alloc] init:"apple" withPrice:150]; • Objective-C class Fruit def init(name, withPrice: price) printf("%s %d\n", name, price) end end Fruit.alloc.init("apple", withPrice:150) • MacRuby キーワード

Slide 11

Slide 11 text

オブジェクト • ルートクラスがCRubyと異なる • CRuby/Object → MacRuby/NSObject • NSObjectはObjective-Cのルートクラス • 全てのオブジェクトはObjective-Cオブジェク ト >> obj = Object.new => >> obj.methods(true,true) => [:clear_history!, :h!, :history!, .... :"performSelectorOnMainThread:withObject:waitUntilDone:", :"performSelectorOnMainThread:withObject:waitUntilDone:modes:", :"performSelector:onThread:withObject:waitUntilDone:modes:", .... ] Objective-C メソッド 利用可能

Slide 12

Slide 12 text

特別なクラス継承 クラス クラスの継承関係 String String → NSMutableString → NSString → NSObject Array Array → NSMutableArray → NSArray → NSObject Hash Hash → NSMutableDictionary → NSDictionary → NSObject Numeric Numeric → NSNumber → NSValue → NSObject Time Time → NSDate → NSObject

Slide 13

Slide 13 text

特別なクラス継承 • StringオブジェクトはNSStringメソッドを 呼び出せる >> framework 'Cocoa' => true >> "abc".writeToFile("/tmp/test.txt", >> atomically:true, >> encoding:NSUTF8StringEncoding, >> error:nil) => true • NSStringには互換性のためRubyメソッドが 追加されている • ArrayやHashなども同様

Slide 14

Slide 14 text

注意点 • NSStringクラスのメソッドが返す文字列はNSString • Stringクラスに追加したメソッドは、NSStringのオブ ジェクトから利用できない(継承関係を確認しよう!) • Stringクラス/NSStringクラスのメソッドが返す文字 列の両方で同じメソッドを使いたい場合には、 NSStringにメソッドを追加すると幸せに。 • NSMutableStringやNSArray、NSDictionaryでも同様 >> str = NSString.stringWithString("abc") => "abc" >> str.class => String #=> 実際はNSStringオブジェクト

Slide 15

Slide 15 text

BridgeSupport • MacRubyはObjective-C Runtimeを使用し てメソッド追加やインスタンス変数など扱う • Objective-C Runtime クラスにどのようなメソッドが実装されてい るか、そのメソッドの引数が幾つあるのか等 定数値、構造体の型、C関数インタフェース、 可変長引数やBlocksを扱うメソッド → BridgeSupportで解決

Slide 16

Slide 16 text

BridgeSupport ~ 準備 ~ • ヘッダファイルからメタデータを生成 $ gen_bridge_metadata -c '-I .' foo.h > foo.bridgesupport 構造体 定数 C関数

Slide 17

Slide 17 text

BridgeSupport ~ 利用 ~ • frameworkにBridgeSupportファイルがあれば、 frameworkと一緒にロードされる(OSX標準の frameworkにはあらかじめ付属) • 手動でBridgeSupportファイルをロードもできる framework "CoreLocation" load_bridge_support_file "foo.bridgesupport" https://github.com/MacRuby/MacRuby/wiki/Loading- Objective-C-Frameworks-and-Bundles

Slide 18

Slide 18 text

定数 • Rubyでは定数は英大文字から始まる • Objective-Cは英子文字で始める定数がある • MacRubyで英大文字に! >> framework "CoreLocation" => true >> p kCLLocationAccuracyBest NameError: undefined local variable or method `kCLLocationAccuracyBest' for main:TopLevel >> p KCLLocationAccuracyBest -1.0 => -1.0

Slide 19

Slide 19 text

Pointer NSError *error; [@"abc" writeToFile: @"/tmp/test.txt" atomically: true encoding: NSUTF8StringEncoding error: &error]; if (error) { // Τϥʔॲཧ } error = Pointer.new(:object) "abc".writeToFile("/tmp/test.txt", atomically: true, encoding: NSUTF8StringEncoding, error: error) if error[0] # Τϥʔॲཧ end • Objective-C • MacRuby ポインタ変数

Slide 20

Slide 20 text

Pointer • ポインタ変数が必要なメソッド呼び出しで 使用する • void型のポインタなど扱えないので注意 • ポインタ変数をできるだけ使わないようにライブ ラリを作っていく方が幸せかも・・・ https://github.com/MacRuby/MacRuby/wiki/Pointer-Class

Slide 21

Slide 21 text

構造体 • 構造体はBoxedクラスを継承したクラスに マッピング • 構造体の型情報はBridgeSupportから取得 >> load_bridge_support_file "foo.bridgesupport" => main >> struct = Fruits.new("Apple", 150) => # >> Fruits.superclass => Boxed https://github.com/MacRuby/MacRuby/wiki/Boxed-Class

Slide 22

Slide 22 text

GCD • MacOSX 10.6、iOS 4で導入 • 非同期処理やマルチスレッドな処理を手軽 に扱える • Dispatchモジュールとして追加 • Dispatch::Queue クラス • Dispatch::Group クラス • Dispatch::Source クラス • Dispatch::Semaphore クラス

Slide 23

Slide 23 text

GCD • 並列処理を手軽に実装可能 • RubyGemsのDispatchを使うと、timesや each、mapで並列処理可能に Dispatch::Queue.concurrent do # 並列処理 end ary.p_each do # 並列処理 end https://github.com/MacRuby/MacRuby/wiki/Dispatch- Module

Slide 24

Slide 24 text

MacRuby vs RubyMotion

Slide 25

Slide 25 text

MacRubyの構成 アプリケーション LLVM ICU 組込みライブラリ Ruby VM libauto 添付ライブラリ Foundation / ライブラリ MacOSX GCDなど

Slide 26

Slide 26 text

RubyMotionの構成 アプリケーション LLVM ICU 組込みライブラリ Ruby VM libauto 独自GC 添付ライブラリ Foundation / ライブラリ iOS GCDなど

Slide 27

Slide 27 text

MacRubyとRubyMotionの 違い • Rubyソースをネイティブの実行ファイルに コンパイル • 添付ライブラリは廃止 (Kernel.#requireメ ソッドも動かない) • GCを独自に実装

Slide 28

Slide 28 text

コンパイルのフロー Rubyソース LLVM中間コード アセンブリファイル オブジェクトファイル 実行ファイル 組込みライブラリ iOS Framework ベンダー static ライブラリ アプリ

Slide 29

Slide 29 text

独自GC • libautoを廃止、参照カウンタ方式のGCを実装 (AppleもlibautoをMacOSX 10.8で廃止リストに入 れるらしい・・・) • Ruby実装として、はじめての参照カウンタ方式 • Objective-Cが参照カウンタでメモリ管理している ので、相性が良い • ベンダー static ライブラリをそのまま使える • MacRubyではObjective-Cを使ったライブラリは - fobjc-gc でコンパイルする必要がある

Slide 30

Slide 30 text

独自GC • オブジェクトの生存期間が、NSAutoReleasePoolが設 定されている区間に依存している • イベントループの区間を越えてオブジェクトを利用する場 合には、インスタンス変数などに格納する • 参照カウンタ方式のため循環参照でメモリリークする ので注意が必要 • メモリ管理を新しくするらしいので、経過を見守りま しょう!! ary = [1, 2, "foo", "bar"] 100_000_000.times do ary << ary end

Slide 31

Slide 31 text

ご清聴 ありがとうございました