From: Masao M. <mu...@hi...> - 2006-06-17 17:50:56
|
むとうです。 リリースに向けバグつぶしを行っていたのでですが さっそく山にぶつかってしまいました。 格闘したのですがとりあえず眠くなったので明日以降に持ち越そうと思います。 一応、今日調べたところまでをメモしておきます。 って、つまり、どなたかお知恵プリーズ! 発端は結構昔にLaurentがMLにポストした内容[1]ですが、 おそらく#1496185[2]も同件だと思います。 [1] http://sourceforge.net/mailarchive/forum.php?forum_id=9443&max_rows=25&style=flat&viewmonth=200512&viewday=6 [2] http://sourceforge.net/tracker/index.php?func=detail&aid=1496185&group_id=53614&atid=470969 サンプルスクリプトは以下になります。 module Fooable def foo p 'foo' end def self.extend_object(o) p "extending #{o}" super end end require 'gtk2' Gtk.init l = Gtk::Label.new l.text = "abc" # works l.extend(Fooable) l.foo # works l.text = "def" # does not work anymore [3] 原因を追ってみると、[3]の呼び出しの中の rbgobj_lookup_class(klass)で 以下のような挙動をしているところが直接的には問題みたいです。 1. rbgtklable.cで_SELF(self)を呼び出す 2. rbgobject.cのrbgobj_instance_from_ruby_object()の G_TYPE_FUNDAMENTAL()でRVAL2GTYPEを呼び出す 3. rbgobj_type.cのrbgobj_lookup_class()に入る 4. 最初、Gtk::Labelをキーにrb_hash_aref()でlookupするが、 ヒットしない(特異クラスだから実際はGtk::Labelのサブクラスで検索ということ?) 5. 次にif (FL_TEST(klass, FL_SINGLETON)) {に入る。 ここで、super = RCLASS(klass)->super;して、 再びrbgobj_lookup_class(super);を呼び出す。 6. で、なぜかここで、rb_hash_aref()に渡されるklassの値が Fooableになっているようで、これが以下のメッセージを出力 しています。 test.rb:31:in `text': undefined method `hash' for #<Fooable:0xb7b8ae98> (NoMethodError) 不思議なのが、5.で以下のようなデバッグコードを入れて実行すると、 if (FL_TEST(klass, FL_SINGLETON)) { super = RCLASS(klass)->super; g_print("rbgobj_lookup_class: %s\n", rb_class2name(super)); g_print("rbgobj_lookup_class: %s\n", rb_class2name(CLASS_OF(super))); } else { 最初のsuperが Gtk::Labelなのですが、CLASS_OF(super)の方がFooableを返すんですよね。 でも、superがGtk::Labelなのに、次のrbgobj_lookup_class(super)のrb_hash_arefで Fooableが呼び出されるのもよくわかりません・・・。 #特異クラス周りの動作がよくわかってないのが問題なんですが・・・。 % ruby -v ruby 1.8.4 (2005-12-24) [i686-linux] はー、難しい。 それでは。 -- .:% Masao Mutoh<mu...@hi...> |