UnboundMethod

未绑定receiver的方法对象的类。它由Module#instance_methodMethod#unbind等生成,在使用UnboundMethod#bind获取receiver以后就可以生成Method对象。

例: 我们可以用UnboundMethod来重写Method 类的开篇例程

class Foo
  def foo() "foo" end
  def bar() "bar" end
  def baz() "baz" end
end

# 将索引和方法的对应关系存入哈希表
# 请注意,这里并不包含receiver的信息
methods = {1 => Foo.instance_method(:foo),
           2 => Foo.instance_method(:bar),
           3 => Foo.instance_method(:baz)}

# 使用索引来调用相关方法
# receiver为任意对象(但必须是Foo 类的实例)
p methods[1].bind(Foo.new).call      # => "foo"
p methods[2].bind(Foo.new).call      # => "bar"
p methods[3].bind(Foo.new).call      # => "baz"

例: 使用UnboundMethod来重定义方法(通常情况下使用aliassuper等)

class Foo
  def foo
    p :foo
  end
  @@orig_foo = instance_method :foo
  def foo
    p :bar
    @@orig_foo.bind(self).call
  end
end

Foo.new.foo

=> :bar
   :foo

超类:

方法:

self[args, ...]
call(args, ...)
call(args, ...) { ... }

如果UnboundMethod尚未bind的话,将无法调用。通常会引发TypeError异常。

class Foo
  def foo
  end
end
Foo.instance_method(:foo).call

# => -:5:in `call': you cannot call unbound method; bind first (TypeError)

ruby 1.8 特性:该方法被取消。

bind(obj)

self绑定到obj上生成并返回一个bound method对象(即Method对象)。只能对下列两种对象进行绑定:调用过unbind方法的对象的类的实例;内部包含(定义某方法的)模块的类的实例。除此以外将引发TypeError异常。

例:

# 类的实例方法的UnboundMethod

class Foo
  def foo
    "foo"
  end
end

# 生成UnboundMethod `m'
p m = Foo.instance_method(:foo) # => #<UnboundMethod: Foo(Foo)#foo>

# 生成Method对象,它以Foo的实例为receiver
p m.bind(Foo.new)               # => #<Method: Foo(Foo)#foo>

# 生成Method对象,它以Foo的Bar子类
# 的实例为receiver(被禁止)
#  ruby 1.8 特性: 取消了该限制

class Bar < Foo
end
# p m.bind(Bar.new)               # => -18:in `bind': bind argument must be an instance of Foo (TypeError)

# 定义同名的特殊方法也不行
class << obj = Foo.new
  def foo
  end
end
p m.bind(obj)                   # => -:25:in `bind': method `foo' overridden (TypeError)

# 模块的实例方法的UnboundMethod

module Foo
  def foo
    "foo"
  end
end

# 生成UnboundMethod `m'
p m = Foo.instance_method(:foo) # => #<UnboundMethod: Foo(Foo)#foo>

# 生成Method对象,它以内部包含Foo的Bar类
# 的实例为receiver
class Bar
  include Foo
end
p m.bind(Bar.new)               # => #<Method: Bar(Foo)#foo>

# Bar的子类也包含Foo,所以没问题
class Baz <Bar
end
p m.bind(Baz.new)               # => #<Method: Baz(Foo)#foo>

# 定义同名的特殊方法也不行
class << obj = Baz.new
  def foo
  end
end
p m.bind(obj)                   # => -:27:in `bind': method `foo' overridden (TypeError)
to_proc

生成一个调用(call)selfProc对象。

unbind

返回self

ruby 1.8 特性:该方法已取消。