🗂

Refinements で refine のブロック外でメソッドが定義されたらどうなる?

2025/01/02に公開

あんまりこういう使い方をしたことがなかったので覚書。
Ruby の Refinements は次のように refine のブロック内で定義したメソッドが using したスコープで利用できるようになります。

module StringEx
  refine String do
    def twice
      self + self
    end
  end
end
using StringEx

# refine 内で定義したメソッドが利用できる
pp "hoge".twice
# => "hogehoge"

pp "hoge".method(:twice).owner
# => #<refinement:String@StringEx>

refine のブロック外でメソッド提議すると?

次のように refine のブロックの外でメソッドを提議するとどうなるのかというとこれも Refinements メソッドとして定義されます。

def define_twice
  define_method(:twice) {
    self + self
  }
end

module StringEx
  refine String do
    # メソッド内でメソッドを提議する
    define_twice
  end
end
using StringEx

# refine 内で定義したメソッドが利用できる
pp "hoge".twice
# => "hogehoge"

pp "hoge".method(:twice).owner
# => #<refinement:String@StringEx>

これも同様に Refinement オブジェクトをレシーバとしてメソッド定義していることになるので利用できます。
それはそうって感じなんですがあんまりこういう書き方をしたことがなかったので覚書。

GitHubで編集を提案

Discussion