I'm trying to understand Ruby's refinements feature, and I've encountered a scenario I don't understand.
Take this example code:
class Traveller
def what_are_you
puts "I'm a Backpacker"
end
def self.preferred_accommodation
puts "Hostels"
end
end
module Refinements
module Money
def what_are_you
puts "I'm a cashed-up hedonist!"
end
module ClassMethods
def preferred_accommodation
puts "Expensive Hotels"
end
end
def self.included(base)
base.extend ClassMethods
end
end
refine Traveller do
include Money
end
end
Now, when I do this in the REPL:
Traveller.new.what_are_you # => I'm a Backpacker
Traveller.preferred_accommodation # => Hostels
using Refinements
Traveller.new.what_are_you # => I'm a cashed-up hedonist!
Traveller.preferred_accommodation # => Hostels (???)
Why is #what_are_you
refined, but .preferred_accommodation
is not?
Traveller.preferred_accommodation
is a class method.Traveller.new.preferred_accommodation
will print what you expect (since you have base class extended on inclusion.) ButTraveller
is an instance ofClass
class. Whether you wantTraveller.preferred_accommodation
refined, you are to refineClass
class. – OfficeholderClass
: they become class methods for all classes? I can't see any advantage of doing that over refining singleton classes, and obvious disadvantages. – ToffeeClass
refinement; the reason I dropped the comment and not an answer is: I wanted to shed a light on what’s going on but not to give a how-to recipe. – Officeholder