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 2284
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.