Method 对象是由 Object#method(:method_name) 方法创建的,且与一个特定对象相关联(而不是与一个类关联)。它们可以被用于调用这个对象内的方法,就像与迭代器关联的块一样。
Method 对象封装了方法的实体 ( 是内容而不是方法名 ) 和被调对象 ( 即持有这个方法的对象 ) 。
Method 对象与 Proc 对象的区别在于:在生成 Method 对象之前必须有可供提取的方法,而 Proc 对象则没有这些限制。由此可见, Proc 对象用过即抛型,而 Method 对象是反复利用型。另外,两者内部包含的代码规模也有不同。 Proc 对象包含的代码较少,而 Method 对象包含的代码较多。
例如:
class Thing
def square(n)
n*n
end
end
aThing = Thing.new # 创建对象
aMethod = aThing.method("square") # 获取与这个对象相关联的 Mehtod 对象。
aMethod.call(9) #-> 81
[ 1, 2, 3 ].collect(&aMethod) #-> [1, 4, 9]
在下面情况, Method 对象是非常有用的:
class Foo
def foo() "foo" end
def bar() "bar" end
def baz() "baz" end
end
obj = Foo.new
# 将索引与方法的关系存入哈希表中
methods = {1 => obj.method(:foo), 2 => obj.method(:bar), 3 => obj.method(:baz)}
# 使用索引调出相关方法
p methods[1].call # => "foo"
p methods[2].call # => "bar"
p methods[3].call # => "baz"
上面的例子中将生成的 Method 对象固化在了哈希表中。若不想固化被调对象时,可以使用 Object#send(:method_name) 方法。
class Foo
def foo() "foo" end
def bar() "bar" end
def baz() "baz" end
end
# 将索引和方法 ( 名 ) 的关系存入哈希表
# 请注意 , 此时并不包括被调的信息
# 所以,你可存入任意的方法名。反正此处无被调信息。
methods = {1 => :foo, 2 => :bar, 3 => :baz}
# 使用索引调出相关方法
# 被调可以是任意对象 ( 并不一定是 Foo 类的实例 )
p Foo.new.send(methods[1]) # => "foo"
p Foo.new.send(methods[2]) # => "bar"
p Foo.new.send(methods[3]) # => "baz"