module C
end
class A
include C
end
class B
include C
end
module Foo
def foo
"foo"
end
def foobar
foo + "bar"
end
end
module R
refine A do
include Foo
end
refine B do
include Foo
end
end
using R
puts A.new.foo # => foo
puts B.new.foo # => foo
puts A.new.foobar # => undefined local variable or method `foo' for #<A:0x007fc71782dcb0> (NameError)
module C
end
class A
include C
end
class B
include C
end
# module_evalで無理やり突っ込むパターン
FooMethods = -> {
def foo
"foo"
end
def foobar
foo + "bar"
end
}
module R
refine A do
module_eval do
FooMethods.call
end
end
refine B do
module_eval do
FooMethods.call
end
end
end
# module_eval内でrefineしちゃうパターン
module R2
%w(A B).each do |klass|
module_eval <<-CODE
refine #{klass} do
def foo
"foo"
end
def foobar
foo + "bar"
end
end
CODE
end
end
# あきらめたパターン
module R3
refine Object do
def foo
if kind_of?(C)
"foo"
else
raise NoMethodError
end
end
def foobar
if kind_of?(C)
foo + "bar"
else
raise NoMethodError
end
end
end
end
using R
puts A.new.foo # => foo
puts B.new.foo # => foo
puts A.new.foobar # => foobar