For a long time I’ve been looking for a way to use Ruby’s refinements without building a class & method setup and then instantiating an instance of the class just to use it. Today I finally found a solution.
module Moo
refine Fixnum do
def to_s
"moo"
end
end
end
# begin/end blocks allow access to local variables
begin # valid Ruby 2.2.3 and NOT Ruby 2.3.0
using Moo
1.to_s
end
# => "moo"
# class syntax has no access to outer local variables
class << Class.new # valid Ruby 2.3.0
using Moo
1.to_s
end
# => "moo"
The best work around I’ve found for accessing values outside the class wood be constants (preferable over global vars). If you wanted to take the extra effort your can have a constant be an instance of Binding to grab the local variables.
class Object
# bv for binding & variable
def bv(a_binding, local_var)
a_binding.local_variable_get local_var
end
end
x = 5
A = binding
class << Class.new
using Moo
bv(A, :x).to_s
end
# => "moo"
I’ve put in a feature request for Ruby’s using method to take a block syntax and allow access to local variables Feature Request #12281. So this would bring back the convenience available in Ruby 2.2.3.