Ruby の refinements で特異メソッドを定義する時の注意
さて、次のようにクラスオブジェクトに対して特異メソッドを定義するとエラーになります。
module StringEx refine String do class << self def homu "homu" end end end end using StringEx # Error: undefined method `homu' for String:Class (NoMethodError) p String.homu
つい、通常のクラスと同じように class << self
を行いたくなるんですが、これでは上手く動作しません。
ここでいう self
は string
ではなくて refinement
のオブジェクトでラップされた String
なので、これでは String
に特異メソッドは定義されないからです。
[String.singleton_class
を使う]
なので、self
ではなくて String.singleton_class
を使用すると動作します。
module StringEx refine String.singleton_class do def homu "homu" end end end module M using StringEx # OK 呼び出せる p String.homu # => "homu" end module M2 # NG 呼び出せない # error: undefined method `homu' for String:Class (NoMethodError) p String.homu end
これでおっけー