レシーバを持たないメソッドオブジェクトのクラスです。 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_proc
self
を call
する Proc オブジェクトを生成して返します。
ruby 1.7 feature: このメソッドはなくなりました。
unbind
self
を返します。
ruby 1.8 feature: このメソッドはなくなりました。