RubyCocoa 今日あたりのコミット 2013-11-28
ruby-2.0対応の準備とか。
- 名前が未定義のときModule#nameがruby-2.0ではnilを、1.8では""を返すという差異によるエラーを修正。to_s入れただけ。(r2509)
- ruby-1.8.4以前用のコードを削除。(r2510, r2511)
- ruby-2.0でのエラーを修正。requireとeucなファイルへのマジックコメント。(r2512)
OSX.__rebind_umethod__ ってなに?
現時点でruby-2.0でテストを流すと次のエラーがでる。
"/opt/local/bin/ruby2.0" -I../ext/rubycocoa -I../lib testall.rb /.../RubyCocoa.framework/Resources/ruby/osx/objc/oc_import.rb:781:in `__rebi nd_umethod__': wrong argument type UnboundMethod (expected Data) (TypeError) from /.../RubyCocoa.framework/Resources/ruby/osx/objc/oc_import.rb:7 81:in `_register_method'
エラーそのものは書いてあるとおりで、__rebind_umethod__の実態であるところのmdl_osxobjc.mの関数にあるようにData_Get_Struct()に渡してるumethodがDataクラスじゃないからダメってこと。ちゅーか逆に、なぜ1.8だと通ってたのかがわからん。
// FIXME: this is a silly hack. struct RB_METHOD { VALUE klass, rklass; // ... }; static VALUE osx_mf_rebind_umethod(VALUE rcv, VALUE klass, VALUE umethod) { struct RB_METHOD *data; Data_Get_Struct(umethod, struct RB_METHOD, data); data->rklass = klass; return Qnil; }
それはそれとして、osx/objc/oc_import.rbの下のほうのObjectいじってるとこと、この__rebind_umethod__がなにをしているかを調べてみた。
RubyCocoaでは、オープンクラス的にObjective-Cのクラスにメソッドを追加することができる。
module OSX class NSData def foo(args) : end end end
クラスメソッドを呼び出すときなどは、const_missingで処理できるけれど、上記のようなクラス定義のときにはconst_missingでなく新規のクラス定義になってしまう。これをメソッド定義時に強引にクラスを差し替えて実現している。それが上記の__rebind_umethod__での処理になっている。
2.0でこれどうするかって考えると、これはなくしたほうがよいよね。ぜったいヤバそうだし。
- フレームワークのロード時(require_framework)
- アプリ起動時(RBApplicationInit)
に、OSX.ns_importでクラスを実体化してやるってのが妥当な落としどころかなあ。