trema / trema-edge

Transient repository for Trema OF1.3 branch
27 stars 14 forks source link

TremaEdgeでPioが動作しない #88

Closed proshiba closed 10 years ago

proshiba commented 10 years ago

TremaEdgeで基底クラス(Objectクラス)に、arrayとかstringという クラスメソッドが追加されているせいで、Pioが使えません。 ↓以下みたいにして確認したら、ObjectクラスでarrayもstringもTrueでした。


class Fuga end p Fuga.superclass # => Object class p Fuga.superclass.respond_to?("array") # => true p Fuga.superclass.respond_to?("string") # => true


ここで、Objectクラスが編集されているせいで、Tremaに関係しないクラスでも 普通にarrayやらstringを常に保持しており、 Pio内部でやってるBinDataを使った宣言の箇所でエラーになりました。

以下のように、TremaEdgeが持っていない名前で宣言するように指定すれば、 正常に動作しました。


・ string => BinData::Stringを継承した自作Typeに変更 class PioString < BinData::String end ※ stringからpio_string に宣言時に名前を変更 ・ array => BinData::Arrayを継承した自作Typeに変更 class PioArray < BinData::Array end ※ arrayからpio_array に宣言時に名前を変更


宣言名が紛らわしくなるため、出来ましたら修正をお願いします。

sugyo commented 10 years ago

どうも、self.class.class_eval している箇所が Object にmethod を追加しているようです。 self.class.class_eval は、いくつかあるのですが、下記のパッチで

p Fuga.superclass.respond_to?("array") # => false

になりました。 でも、inherited から define_accessor_meth が呼ばれるので、きっかけとなったクラスでなく、親のクラスに登録されます、それは意図していないのかもしれません。inherited で受け取った 子のclass に対してclass_eval をしないといけないような気もします。

diff --git a/ruby/trema/accessor.rb b/ruby/trema/accessor.rb
index adf8f3b..fbf5130 100644
--- a/ruby/trema/accessor.rb
+++ b/ruby/trema/accessor.rb
@@ -82,8 +82,8 @@ module Trema

       def define_accessor_meth meth
-        self.class.class_eval do
-          define_method :"#{ meth }" do | *args |
+        self.class_eval do
+          define_singleton_method :"#{ meth }" do | *args |
             attrs = args
             opts = extract_options!( args )
             check_args args
proshiba commented 10 years ago

なるほどですね。このやり方で親クラスに登録されるとは知りませんでした。 とりあえずは回避策でよけられているので、修正されることをお待ちしております。

yasuhito commented 10 years ago

@proshiba すぎょうさんの修正を適用してみました。対応が遅れてすみません。。