Module::instance_methodでレシーバと関連付いてないメソッド(UnboundMethod)が生成される。元に戻したい場合は、そのメソッドが定義されているクラスその物に対してもう一度bindしてあげる必要がある。しかーし、Object.methodで取得してbind→ダメ、method.inspectからクラス名を取り出してModule.const_getで取得してみる→ダメ。以下メモ。
eval.c:umethod_bind if (FL_TEST(data->rklass, FL_SINGLETON)) { rb_raise(rb_eTypeError, "singleton method bound for a different object"); } ruby.h #define SPECIAL_CONST_P(x) (IMMEDIATE_P(x) || !RTEST(x)) #define FL_ABLE(x) (!SPECIAL_CONST_P(x)) #define FL_TEST(x,f) (FL_ABLE(x)?(RBASIC(x)->flags&(f)):0) #define FL_SINGLETON FL_USER0 struct RBasic { unsigned long flags; VALUE klass; }; FL_SET(klass, FLAG)でセットする FL_SINGLETONがセットされているのはclass.cの VALUE rb_singleton_class_clone(obj)とVALUE rb_make_metaclass(obj,super)
method_missingで頑張るという手もなくもないが、それをRuby(ruby_1_8)が受け付けるか微妙だ。