oop/refinement_indirect_calls.rb
tests/_examples/oop/refinement_indirect_calls.rb in the metorex repository.
# A refinement in force covers a call written out and one reached through
# `send`, a Symbol turned into a block, or text being built.
class Refined
def foo
"plain"
end
def to_s
"plain"
end
end
refinement = Module.new do
refine Refined do
def foo
"refined"
end
def to_s
"refined"
end
end
end
held = []
Module.new do
using refinement
subject = Refined.new
held << subject.foo
held << subject.send(:foo)
held << subject.__send__(:foo)
held << subject.public_send(:foo)
held << [Refined.new].map(&:foo).first
held << "#{subject}"
end
puts held.inspect
puts Refined.new.foo
# The same name asked about rather than called.
Module.new do
using refinement
subject = Refined.new
puts subject.respond_to?(:foo)
puts subject.method(:foo).call
puts subject.method(:foo).class == Method
end
# A refinement on a module reaches what takes that module in, a method the
# object's own class writes stands ahead of a refinement on an ancestor, and
# a module's own refinement stands ahead of one it includes.
module Countable
def described
"plain"
end
end
class Holder
include Countable
end
class Narrower < Holder
def described
"from the subclass"
end
end
on_module = Module.new do
refine Countable do
def described
"from the module refinement"
end
end
end
Module.new do
using on_module
puts Holder.new.described
puts Narrower.new.described
end
Output:
["refined", "refined", "refined", "refined", "refined", "refined"]
plain
true
refined
true
from the module refinement
from the subclass