# Method

obj.method(:method_name) によりオブジェクト化され たメソッドオブジェクトのクラスです。メソッドの実体（名前でなく）とレシー バの組を封入します。Proc オブジェクトと違ってコンテキストを保持 しません。

Proc との差…`Method` は取り出しの対象であるメソッドが なければ作れませんが、`Proc` は準備なしに作れます。その点から `Proc` は使い捨てに向き、`Method` は何度も繰り返し生成する 場合に向くと言えます。また内包するコードの大きさという点では `Proc` は小規模、`Method` は大規模コードに向くと言えます。

例:

- 既存のメソッドを Method オブジェクト化する (Object#method を参照)

      class Foo
        def foo(arg)
          "foo called with arg #{arg}"
        end
      end

      m = Foo.new.method(:foo)

      p m             # => #<Method: Foo#foo>
      p m.call(1)     # => "foo called with arg 1"

- 名前のないメソッド(の代わり)が必要なら Proc を使うと良い

      pr = Proc.new {|arg|
        "proc called with arg #{arg}"
      }

      p pr            # => #<Proc:0x401b1fcc>
      p pr.call(1)    # => "proc called with arg 1"

- 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を使う方法も有用。

      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"

## スーパークラス:

- Object

## メソッド:

`self[arg, ...]`
`call(arg ... )`
`call(arg ... ) { ... }`

  メソッドオブジェクトに封入されているメソッドを起動します。 引数やブロックはそのままメソッドに渡されます。

  `self[]` の形の呼び出しは通常のメソッド呼び出しに見た目を 近付けるためだけに用意されたもので、Array#[]のような 他の [] メソッドとの意味的な関連性はありません。

  メソッドオブジェクトが汚染されている場合、そのメソッドは、セーフレ ベル 4 で実行されます (セーフレベルに関するその他の詳細を参照)。

`arity`

  メソッドオブジェクトの引数の数を返します。`self` が引数の数を 可変長で受け取れる場合

      -(最低限必要な数 + 1)

  を返します。

`inspect`

  Object#inspect 参照。以下の形式の文字列を返し ます。

      #<Method: klass1(klass2)#method>                (形式1)

  klass1 は、Method#inspect では、レシーバのクラス名、 UnboundMethod#inspect では、UnboundMethod オブジェクトの生成 元となったクラス／モジュール名です。

  klass2 は、実際にそのメソッドを定義しているクラス／モジュール名、 method は、メソッド名を表します。

      module Foo
        def foo
          "foo"
        end
      end
      class Bar
        include Foo
        def bar
        end
      end

      p Bar.new.method(:foo)        # => #<Method: Bar(Foo)#foo>
      p Bar.new.method(:bar)        # => #<Method: Bar(Bar)#bar>

  ruby 1.7 feature: klass1 と klass2 が同じ場合は以下の形式になります。

      #<Method: klass1#method>                        (形式2)

  ruby 1.7 feature: 特異メソッドに対しては、

      #<Method: obj.method>                           (形式3)
      #<Method: klass1(klass2).method>                (形式4)

  という形式の文字列を返します。二番目の形式では klass1 はレシーバ、 klass2 は実際にそのメソッドを定義しているオブジェクトになります。

      # オブジェクトの特異メソッド
      obj = ""
      class <<obj
        def foo
        end
      end
      p obj.method(:foo)      # => #<Method: "".foo>

      # クラスメソッド(クラスの特異メソッド)
      class Foo
        def Foo.foo
        end
      end
      p Foo.method(:foo)      # => #<Method: Foo.foo>

      # スーパークラスのクラスメソッド
      class Bar < Foo
      end
      p Bar.method(:foo)      # => #<Method: Bar(Foo).foo>

      # 以下は(形式1)の出力になる
      module Baz
        def baz
        end
      end

      class <<obj
        include Baz
      end
      p obj.method(:baz)      # => #<Method: Object(Baz)#baz>

`to_proc`

  `self` を `call` する Proc オブジェクトを生成して返 します。

`unbind`

  `self` のレシーバとの関連を取り除いた UnboundMethod オブ ジェクトを生成して返します。

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