bind(p1)
public
Bind umeth to obj. If Klass was the class from which
umeth was obtained, obj.kind_of?(Klass) must be true.
class A
def test
puts "In test, class = #{self.class}"
end
end
class B < A
end
class C < B
end
um = B.instance_method(:test)
bm = um.bind(C.new)
bm.call
bm = um.bind(B.new)
bm.call
bm = um.bind(A.new)
bm.call
produces:
In test, class = C
In test, class = B
prog.rb:16:in `bind': bind argument must be an instance of B (TypeError)
from prog.rb:16
Show source
static VALUE
umethod_bind(VALUE method, VALUE recv)
{
struct METHOD *data, *bound;
VALUE methclass;
VALUE rclass;
TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
methclass = data->rclass;
if (!RB_TYPE_P(methclass, T_MODULE) &&
methclass != CLASS_OF(recv) && !rb_obj_is_kind_of(recv, methclass)) {
if (FL_TEST(methclass, FL_SINGLETON)) {
rb_raise(rb_eTypeError,
"singleton method called for a different object");
}
else {
rb_raise(rb_eTypeError, "bind argument must be an instance of % "PRIsVALUE,
rb_class_name(methclass));
}
}
method = TypedData_Make_Struct(rb_cMethod, struct METHOD, &method_data_type, bound);
*bound = *data;
bound->me = ALLOC(rb_method_entry_t);
*bound->me = *data->me;
if (bound->me->def) bound->me->def->alias_count++;
rclass = CLASS_OF(recv);
if (BUILTIN_TYPE(bound->defined_class) == T_MODULE) {
VALUE ic = rb_class_search_ancestor(rclass, bound->defined_class);
if (ic) {
rclass = ic;
}
else {
rclass = rb_include_class_new(methclass, rclass);
}
}
bound->recv = recv;
bound->rclass = rclass;
data->ume = ALLOC(struct unlinked_method_entry_list_entry);
return method;
}