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)が受け付けるか微妙だ。