Refinementsはレキシカルスコープという説明をよく聞くけど、どこにコードが書かれているかというよりはusing
を呼んだ後の環境で評価されるかどうかというのが重要。なのでコードの字面でRefinementsで定義したメソッドの呼び出しがusing
より前に書かれていても、先にusing
の方が評価されていれば呼び出せる。
Refinements are only active within a scope after the call to using.
https://docs.ruby-lang.org/en/2.5.0/syntax/refinements_rdoc.html
その1. BEGIN
の中でusing
BEGIN
でusing
を使うとどのコードよりも先にusing
が実行されるため先頭行でusing
を書いたのと同じように働く。
hi
# hi
BEGIN {
using Module.new {
refine(Object) do
def hi
puts "hi"
end
end
}
}
その10. binding
を使う
eval
の第二引数にusing
が効いた環境のbinding
を渡すとusing
で定義したメソッドが使える。
def greeting(b)
eval('hi', b)
end
using Module.new {
refine(Object) do
def hi
puts "hi"
end
end
}
greeting(binding)
Binding#eval
してもよし。
def greeting(b)
b.eval('hi')
end
using Module.new {
refine(Object) do
def hi
puts "hi"
end
end
}
greeting(binding)
10ないじゃん
"10".to_i(2)
# => 2