レシーバを持たないメソッドオブジェクトのクラスです。 Module#instance_method や Method#unbind により生成し、後で UnboundMethod#bind によりレシーバを 割り当てた Method オブジェクトを作ることができます。
例: Method クラスの冒頭にある例を UnboundMethod で書くと以下のようになる
class Foo
def foo() "foo" end
def bar() "bar" end
def baz() "baz" end
end
# 任意のキーとメソッドの関係をハッシュに保持しておく
# レシーバの情報がここにはないことに注意
methods = {1 => Foo.instance_method(:foo),
2 => Foo.instance_method(:bar),
3 => Foo.instance_method(:baz)}
# キーを使って関連するメソッドを呼び出す
# レシーバは任意(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 を使って行う方法(普通は、 alias や super を使う)
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 feature: このメソッドはなくなりました。
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>
# Foo のインスタンスをレシーバとする Method オブジェクトを生成
p m.bind(Foo.new) # => #<Method: Foo(Foo)#foo>
# Foo のサブクラス Bar のインスタンスをレシーバとする Method
# オブジェクトを生成(これは許されない)
# ruby 1.8 feature: 許されるようになりました
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>
# Foo をインクルードしたクラス Bar のインスタンスをレシーバと
# する Method オブジェクトを生成
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_procself を call する Proc オブジェクトを生成して返します。
ruby 1.7 feature: このメソッドはなくなりました。
unbindself を返します。
ruby 1.8 feature: このメソッドはなくなりました。