Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Differences CRuby/MacRuby/RubyMotion

6e8aca910e7ee095397d3b90acb25f6c?s=47 Watson
July 21, 2012

Differences CRuby/MacRuby/RubyMotion

6e8aca910e7ee095397d3b90acb25f6c?s=128

Watson

July 21, 2012
Tweet

Transcript

  1. Differences CRuby/MacRuby/RubyMotion twitter: @watson1978

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

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

    RubyMotion
  4. MacRuby RubyMotionの系譜

  5. 系譜 CRuby MacRuby RubyMotion 2008/02 2011/11 1.9.0 p1 2008/03 v0.11

    2011/11 v1.0 2012/05
  6. CRuby vs MacRuby

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

    ライブラリ OS
  8. MacRubyの構成 アプリケーション YARV LLVM 鬼車 ICU 組込みライブラリ GVL Ruby VM

    GC libauto 添付ライブラリ Foundation / ライブラリ MacOSX GCDなど
  9. MacRubyとCRubyの違い • GVLを廃止 → 各スレッドが並列動作可能 • GC → libauto •

    (RubyCocoaでRubyとMacOSXのGCの動作がコン フリクトし、クラッシュしたり・・・) • キーワード付き引数をサポート • ルートクラスObject → NSObject • Objective-Cの定数や構造体、GCDなどを扱 うために独自機能を追加
  10. キーワード付き引数 - (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 キーワード
  11. オブジェクト • ルートクラスがCRubyと異なる • CRuby/Object → MacRuby/NSObject • NSObjectはObjective-Cのルートクラス •

    全てのオブジェクトはObjective-Cオブジェク ト >> obj = Object.new => <NSObject: 0x4007e2160> >> obj.methods(true,true) => [:clear_history!, :h!, :history!, .... :"performSelectorOnMainThread:withObject:waitUntilDone:", :"performSelectorOnMainThread:withObject:waitUntilDone:modes:", :"performSelector:onThread:withObject:waitUntilDone:modes:", .... ] Objective-C メソッド 利用可能
  12. 特別なクラス継承 クラス クラスの継承関係 String String → NSMutableString → NSString →

    NSObject Array Array → NSMutableArray → NSArray → NSObject Hash Hash → NSMutableDictionary → NSDictionary → NSObject Numeric Numeric → NSNumber → NSValue → NSObject Time Time → NSDate → NSObject
  13. 特別なクラス継承 • StringオブジェクトはNSStringメソッドを 呼び出せる >> framework 'Cocoa' => true >>

    "abc".writeToFile("/tmp/test.txt", >> atomically:true, >> encoding:NSUTF8StringEncoding, >> error:nil) => true • NSStringには互換性のためRubyメソッドが 追加されている • ArrayやHashなども同様
  14. 注意点 • NSStringクラスのメソッドが返す文字列はNSString • Stringクラスに追加したメソッドは、NSStringのオブ ジェクトから利用できない(継承関係を確認しよう!) • Stringクラス/NSStringクラスのメソッドが返す文字 列の両方で同じメソッドを使いたい場合には、 NSStringにメソッドを追加すると幸せに。

    • NSMutableStringやNSArray、NSDictionaryでも同様 >> str = NSString.stringWithString("abc") => "abc" >> str.class => String #=> 実際はNSStringオブジェクト
  15. BridgeSupport • MacRubyはObjective-C Runtimeを使用し てメソッド追加やインスタンス変数など扱う • Objective-C Runtime クラスにどのようなメソッドが実装されてい るか、そのメソッドの引数が幾つあるのか等

    定数値、構造体の型、C関数インタフェース、 可変長引数やBlocksを扱うメソッド → BridgeSupportで解決
  16. BridgeSupport ~ 準備 ~ • ヘッダファイルからメタデータを生成 $ gen_bridge_metadata -c '-I

    .' foo.h > foo.bridgesupport <?xml version='1.0'?> <!DOCTYPE signatures SYSTEM "file://localhost/System/Library/ DTDs/BridgeSupport.dtd"> <signatures version='1.0'> <struct type='{Fruits=&quot;name&quot;*&quot;price&quot;i}' name='Fruits'/> <enum name='TEST_CONST' value='42'/> <function name='init_fruits'> <arg type='^{Fruits=*i}'/> </function> </signatures> 構造体 定数 C関数
  17. 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
  18. 定数 • 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
  19. 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 ポインタ変数
  20. Pointer • ポインタ変数が必要なメソッド呼び出しで 使用する • void型のポインタなど扱えないので注意 • ポインタ変数をできるだけ使わないようにライブ ラリを作っていく方が幸せかも・・・ https://github.com/MacRuby/MacRuby/wiki/Pointer-Class

  21. 構造体 • 構造体はBoxedクラスを継承したクラスに マッピング • 構造体の型情報はBridgeSupportから取得 >> load_bridge_support_file "foo.bridgesupport" =>

    main >> struct = Fruits.new("Apple", 150) => #<Fruits name="Apple" price=150> >> Fruits.superclass => Boxed https://github.com/MacRuby/MacRuby/wiki/Boxed-Class
  22. GCD • MacOSX 10.6、iOS 4で導入 • 非同期処理やマルチスレッドな処理を手軽 に扱える • Dispatchモジュールとして追加

    • Dispatch::Queue クラス • Dispatch::Group クラス • Dispatch::Source クラス • Dispatch::Semaphore クラス
  23. GCD • 並列処理を手軽に実装可能 • RubyGemsのDispatchを使うと、timesや each、mapで並列処理可能に Dispatch::Queue.concurrent do # 並列処理

    end ary.p_each do # 並列処理 end https://github.com/MacRuby/MacRuby/wiki/Dispatch- Module
  24. MacRuby vs RubyMotion

  25. MacRubyの構成 アプリケーション LLVM ICU 組込みライブラリ Ruby VM libauto 添付ライブラリ Foundation

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

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

    GCを独自に実装
  28. コンパイルのフロー Rubyソース LLVM中間コード アセンブリファイル オブジェクトファイル 実行ファイル 組込みライブラリ iOS Framework ベンダー

    static ライブラリ アプリ
  29. 独自GC • libautoを廃止、参照カウンタ方式のGCを実装 (AppleもlibautoをMacOSX 10.8で廃止リストに入 れるらしい・・・) • Ruby実装として、はじめての参照カウンタ方式 • Objective-Cが参照カウンタでメモリ管理している

    ので、相性が良い • ベンダー static ライブラリをそのまま使える • MacRubyではObjective-Cを使ったライブラリは - fobjc-gc でコンパイルする必要がある
  30. 独自GC • オブジェクトの生存期間が、NSAutoReleasePoolが設 定されている区間に依存している • イベントループの区間を越えてオブジェクトを利用する場 合には、インスタンス変数などに格納する • 参照カウンタ方式のため循環参照でメモリリークする ので注意が必要

    • メモリ管理を新しくするらしいので、経過を見守りま しょう!! ary = [1, 2, "foo", "bar"] 100_000_000.times do ary << ary end
  31. ご清聴 ありがとうございました