class UnboundMethod

[edit]

要約

レシーバを持たないメソッドを表すクラスです。呼び出すためにはレシーバにバインドする必要があります。

Module#instance_methodMethod#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 == other -> bool[permalink][rdoc][edit]
eql?(other) -> bool

自身と other が同じクラスあるいは同じモジュールの同じメソッドを表す場合に true を返します。そうでない場合に false を返します。

[PARAM] other:
自身と比較したいオブジェクトを指定します。


a = String.instance_method(:size)
b = String.instance_method(:size)
p a == b                            #=> true

c = Array.instance_method(:size)
p a == c                            #=> false
arity -> Integer[permalink][rdoc][edit]

メソッドが受け付ける引数の数を返します。

ただし、メソッドが可変長引数を受け付ける場合、負の整数

-(必要とされる引数の数 + 1)

を返します。C 言語レベルで実装されたメソッドが可変長引数を受け付ける場合、-1 を返します。



class C
  def one;    end
  def two(a); end
  def three(*a);  end
  def four(a, b); end
  def five(a, b, *c);    end
  def six(a, b, *c, &d); end
end

p C.instance_method(:one).arity     #=> 0
p C.instance_method(:two).arity     #=> 1
p C.instance_method(:three).arity   #=> -1
p C.instance_method(:four).arity    #=> 2
p C.instance_method(:five).arity    #=> -3
p C.instance_method(:six).arity     #=> -3


String.instance_method(:size).arity      #=> 0
String.instance_method(:replace).arity   #=> 1
String.instance_method(:squeeze).arity   #=> -1
String.instance_method(:count).arity     #=> -1
bind(obj) -> Method[permalink][rdoc][edit]

self を obj にバインドした Method オブジェクトを生成して返します。

[PARAM] obj:
自身をバインドしたいオブジェクトを指定します。ただしバインドできるのは、生成元のクラスかそのサブクラスのインスタンスのみです。
[EXCEPTION] TypeError:
objがbindできないオブジェクトである場合に発生します


# クラスのインスタンスメソッドの UnboundMethod の場合
class Foo
  def foo
    "foo"
  end
end

# UnboundMethod `m' を生成
p m = Foo.instance_method(:foo) # => #<UnboundMethod: Foo#foo>

# Foo のインスタンスをレシーバとする Method オブジェクトを生成
p m.bind(Foo.new)               # => #<Method: Foo#foo>

# Foo のサブクラス Bar のインスタンスをレシーバとする Method
class Bar < Foo
end
p m.bind(Bar.new)               # => #<Method: Bar(Foo)#foo>


# モジュールのインスタンスメソッドの UnboundMethod の場合
module Foo
  def foo
    "foo"
  end
end

# UnboundMethod `m' を生成
p m = Foo.instance_method(:foo) # => #<UnboundMethod: Foo#foo>

# Foo をインクルードしたクラス Bar のインスタンスをレシーバと
# する Method オブジェクトを生成
class Bar
  include Foo
end
p m.bind(Bar.new)               # => #<Method: Bar(Foo)#foo>

[SEE_ALSO] UnboundMethod#bind_call

bind_call(recv, *args) -> object[permalink][rdoc][edit]
bind_call(recv, *args) { ... } -> object

self を recv に bind して args を引数として呼び出します。

self.bind(recv).call(*args) と同じ意味です。


puts Kernel.instance_method(:inspect).bind_call(BasicObject.new) # => #<BasicObject:0x000055c65e8ea7b8>

[SEE_ALSO] UnboundMethod#bind, Method#call

clone -> UnboundMethod[permalink][rdoc][edit]

自身を複製した UnboundMethod オブジェクトを作成して返します。



a = String.instance_method(:size)
b = a.clone

a == b       # => true
hash -> Integer[permalink][rdoc][edit]

自身のハッシュ値を返します。



a = method(:==).unbind
b = method(:eql?).unbind
p a.eql? b          # => true
p a.hash == b.hash  # => true
p [a, b].uniq.size  # => 1
inspect -> String[permalink][rdoc][edit]
to_s -> String

self を読みやすい文字列として返します。

詳しくは Method#inspect を参照してください。



String.instance_method(:count).inspect   # => "#<UnboundMethod: String#count>"

[SEE_ALSO] Method#inspect

name -> Symbol[permalink][rdoc][edit]

このメソッドの名前を返します。



a = String.instance_method(:size)
a.name   # => :size
original_name -> Symbol[permalink][rdoc][edit]

オリジナルのメソッド名を返します。



class C
  def foo; end
  alias bar foo
end
C.instance_method(:bar).original_name # => :foo

[SEE_ALSO] Method#original_name

owner -> Class | Module[permalink][rdoc][edit]

このメソッドが定義されている class か module を返します。



Integer.instance_method(:to_s).owner   # => Integer
Integer.instance_method(:to_c).owner   # => Numeric
Integer.instance_method(:hash).owner   # => Kernel
parameters -> [object][permalink][rdoc][edit]

UnboundMethod オブジェクトの引数の情報を返します。

詳しくは Method#parameters を参照してください。

[SEE_ALSO] Proc#parameters, Method#parameters

source_location -> [String, Integer] | nil[permalink][rdoc][edit]

ソースコードのファイル名と行番号を配列で返します。

その手続オブジェクトが ruby で定義されていない(つまりネイティブである)場合は nil を返します。



require 'time'

Time.instance_method(:zone).source_location       # => nil
Time.instance_method(:httpdate).source_location   # => ["/Users/user/.rbenv/versions/2.4.3/lib/ruby/2.4.0/time.rb", 654]

[SEE_ALSO] Proc#source_location, Method#source_location

super_method -> UnboundMethod | nil[permalink][rdoc][edit]

self 内で super を実行した際に実行されるメソッドを UnboundMethod オブジェクトにして返します。

[SEE_ALSO] Method#super_method