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 を行いたくなるんですが、これでは上手く動作しません。 ここでいう selfstring ではなくて refinement のオブジェクトでラップされた String なので、これでは String に特異メソッドは定義されないからです。

[self ではなくて String を使用する]

なので、self ではなくて String を使用すると動作します。

module StringEx
    refine String do
        class << String
            def homu
                "homu"
            end
        end
    end
end

using StringEx

p String.homu
# => "homu"

これでおっけー