# UnboundMethod

レシーバを持たないメソッドオブジェクトのクラスです。 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

## スーパークラス:

- Method version 1.6 以前
- Object (version 1.8 以降)

## メソッド:

`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: このメソッドはなくなりました。

links: [Method] [Module] [Object] [Proc] [TypeError] [UnboundMethod] [ruby 1.7 feature] [ruby 1.8 feature] [クラス／メソッドの定義] [メソッド呼び出し]
reverse links: [1.6.8から1.8.0への変更点(まとめ)] [FAQ::組み込みライブラリ] [Marshal] [Method] [Module] [ruby 1.6 feature] [ruby 1.8 feature] [機能別索引] [組み込みクラス／モジュール／例外クラス]