UnboundMethod

プログラミング言語 Ruby リファレンスマニュアル
うろうろしてたら,見かけたので.

レシーバを持たないメソッドオブジェクトのクラスです。 Module#instance_method や Method#unbind により生成し、後で UnboundMethod#bind によりレシーバを割り当てた Method オブジェクトを作ることができます。

何に使うんだ???

こんな感じに使える

とりあえずinjectでためす.

inject = Array.instance_method(:inject) # こいつがUnboundMethod

arr = [(1 .. 10).to_a, (11 .. 20).to_a]

arr.each { |e| p inject.bind(e).call{|r, x| r += x} }
=>
55
155

UnboundMethod#bindでbindできるのは,unbindしたオブジェクトのクラスか,メソッド定義もとのモジュールをインクルードしたクラスのインスタンスでなければならない.ただ,オブジェクトにunbound methodと同名の特異メソッドが定義されていると,ダメ.何か有効な使い方はないかと考えてみる.

とりあえず特異メソッド

レシーバが変わるときにその効果を発揮するので,unbound methodのレシーバに特異メソッドを呼ばせれば効果的?とか考えたけど,実際書いてみるとどの辺が効果的?という感じ.

class Hoge
  attr_reader :a
  def initialize(a)
    @a = a
  end
  
  def piyo
    p self.fuga.reverse
  end
end

m = Hoge.instance_method(:piyo)

objs = []

class << (objs << Hoge.new([1,2,3])).last
  def fuga
    return @a.map{|e| e.to_s}
  end
end

class << (objs << Hoge.new("i love ruby")).last
  def fuga
    return @a.capitalize
  end
end

objs.each { |e| m.bind(e).call }
=>
["3", "2", "1"]
"ybur evol I"
objs.each {|e| e.piyo}

のほうが見やすいんとちゃうかな.色々書いてると,だんだんと気持ち悪くなってきたので,寝る.