我正在尝试理解Ruby的改进特性,我遇到了一个我不理解的场景。
以下面的示例代码为例:
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现在,当我在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 (???)为什么#what_are_you是精炼的,而.preferred_accommodation却不是?
发布于 2015-01-08 07:33:07
正如@MasashiMiyazaki所解释的,您必须细化两个类:Traveller和Traveller的单例类。这实际上允许您简化代码:
module Money
refine Traveller do
def what_are_you
puts "I'm a cashed-up hedonist!"
end
end
refine Traveller.singleton_class do
def preferred_accommodation
puts "Expensive Hotels"
end
end
end
Traveller.new.what_are_you #=> I'm a Backpacker
Traveller.preferred_accommodation #=> Hostels
using Money
Traveller.new.what_are_you #=> I'm a cashed-up hedonist!
Traveller.preferred_accommodation #=> Expensive Hotels此外,通过将上述三条语句放在一个模块中,这两种方法的精化版本仅限于该模块:
module M
using Money
Traveller.new.what_are_you #=> I'm a cashed-up hedonist!
Traveller.preferred_accommodation #=> Expensive Hotels
end
Traveller.new.what_are_you #=> I'm a Backpacker
Traveller.preferred_accommodation #=> Hostels发布于 2015-01-08 06:43:40
您需要使用singleton_class作用域调用refine来覆盖类方法。通过将以下代码添加到精化模块(而不是self.included )中,您可以获得预期的结果。
module Refinements
refine Traveller.singleton_class do
include Money::ClassMethods
end
end本文(http://timelessrepo.com/refinements-in-ruby)将帮助您更好地理解细化。
https://stackoverflow.com/questions/27833447
复制相似问题