Class: UnboundMethod
Overview
Ruby supports two forms of objectified methods. ::Class ::Method is used to represent methods that are associated with a particular object: these method objects are bound to that object. Bound method objects for an object can be created using Object#method.
Ruby also supports unbound methods; methods objects that are not associated with a particular object. These can be created either by calling Module#instance_method or by calling unbind on a bound method object. The result of both of these is an UnboundMethod object.
Unbound methods can only be called after they are bound to an object. That object must be a kind_of? the method's original class.
class Square
def area
@side * @side
end
def initialize(side)
@side = side
end
end
area_un = Square.instance_method(:area)
s = Square.new(12)
area = area_un.bind(s)
area.call #=> 144
Unbound methods are a reference to the method at the time it was objectified: subsequent changes to the underlying class will not affect the unbound method.
class Test
def test
:original
end
end
um = Test.instance_method(:test)
class Test
def test
:modified
end
end
t = Test.new
t.test #=> :modified
um.bind(t).call #=> :original
Instance Method Summary
-
#==(other_meth) ⇒ Boolean
(also: #eql?)
Alias for Method#==.
-
#arity ⇒ Integer
Alias for Method#arity.
-
#bind(obj) ⇒ method
Bind umeth to obj.
-
#clone ⇒ Method
Alias for Method#clone.
-
#eql?(other_meth) ⇒ Boolean
Alias for #==.
-
#hash ⇒ Integer
Alias for Method#hash.
-
#to_s ⇒ String
Alias for Method#inspect.
-
#name ⇒ Symbol
Alias for Method#name.
-
#original_name ⇒ Symbol
Alias for Method#original_name.
-
#owner ⇒ class_or_module
Alias for Method#owner.
-
#parameters ⇒ Array
Alias for Method#parameters.
-
#source_location ⇒ Array, Integer
Alias for Method#source_location.
-
#super_method ⇒ Method
Alias for Method#super_method.
-
#to_s
Alias for Method#inspect.
Instance Method Details
#==(other_meth) ⇒ Boolean Also known as: #eql?
Alias for Method#==.
#arity ⇒ Integer
Alias for Method#arity.
#bind(obj) ⇒ method
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
# File 'proc.c', line 2240
static VALUE
umethod_bind(VALUE method, VALUE recv)
{
struct METHOD *data, *bound;
VALUE methclass, klass;
TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
methclass = data->me->owner;
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,
methclass);
}
}
klass = CLASS_OF(recv);
method = TypedData_Make_Struct(rb_cMethod, struct METHOD, &method_data_type, bound);
RB_OBJ_WRITE(method, &bound->recv, recv);
RB_OBJ_WRITE(method, &bound->klass, data->klass);
RB_OBJ_WRITE(method, &bound->me, rb_method_entry_clone(data->me));
if (RB_TYPE_P(bound->me->owner, T_MODULE)) {
VALUE ic = rb_class_search_ancestor(klass, bound->me->owner);
if (ic) {
klass = ic;
}
else {
klass = rb_include_class_new(methclass, klass);
}
RB_OBJ_WRITE(method, &bound->me, rb_method_entry_complement_defined_class(bound->me, bound->me->called_id, klass));
}
return method;
}
#clone ⇒ Method
Alias for Method#clone.
#==(other_meth) ⇒ Boolean
#eql?(other_meth) ⇒ Boolean
Boolean
#eql?(other_meth) ⇒ Boolean
Alias for #==.
#hash ⇒ Integer
Alias for Method#hash.
#to_s ⇒ String
Alias for Method#inspect.
#name ⇒ Symbol
Alias for Method#name.
#original_name ⇒ Symbol
Alias for Method#original_name.
#owner ⇒ class_or_module
Alias for Method#owner.
#parameters ⇒ Array
Alias for Method#parameters.
#source_location ⇒ Array, Integer
Alias for Method#source_location.
#super_method ⇒ Method
Alias for Method#super_method.
#to_s
Alias for Method#inspect.