Bye Bye Moore

PoCソルジャーな零細事業主が作業メモを残すブログ

UnboundMethodという奇怪なクラスについて(その2)

UnboudMethodは、メソッド定義が先に来て、実体を後から渡します。

mtd = String.instance_method(:upcase)
#=> #<UnboundMethod: String#upcase>

mtd.bind("hoge").call
#=> "HOGE"

mtd.bind("gya").call
#=> "GYA"

あるいは、次の例のようにその時点のメソッド定義を退避させておき
後々呼び出すなんて使い方もできるようです。
先日のextendとは逆の用法ですね

class Test
  def test
    :original
  end
end
um = Test.instance_method(:test)
class Test
  def test
    :modified
  end
end
t = Test.new
t.test            #=> :modified
um.bind(t).call   #=> :original

内部実装について

UnboundMethodに関して色々なサイトを巡った所、
C言語系の関数ポインタに近い」といった内容の記述が多く見られました。

参考サイトでは

ちなみに、Ruby処理系内部の実装では、MethodもUnboundMethodもどちらもstruct METHODだ。UnboundMethodはselfを記録しておくポインタを使ってないだけ。

との説明がありました。

UnboundMethodとMethodの使い分け

UnboundMethodとMethodは
 - 対象インスタンスと使うメソッドは決まってるけど実体がまだない場合は、UnboundMethod
 - インスタンスの実体が決まっている場合にはMethod
という使い分けができそうです。