如何在Ruby中优化模块方法?

10
你可以使用以下方式优化你的类:
module RefinedString
  refine String do
    def to_boolean(text)
    !!(text =~ /^(true|t|yes|y|1)$/i)
    end
  end
end

但如何优化模块方法?这样做:
module RefinedMath
  refine Math do
    def PI
      22/7
    end
  end
end

错误: TypeError: 参数类型应为类 (实际为模块)

2个回答

16

这段代码将会运行:

module Math
  def self.pi
    puts 'original method'
   end
end

module RefinementsInside
  refine Math.singleton_class do
    def pi
      puts 'refined method'
    end
  end
end

module Main
  using RefinementsInside
  Math.pi #=> refined method
end

Math.pi #=> original method

解释:

定义一个模块#method相当于在它的#singleton_class上定义一个实例方法(等同于)


1
细化(refinements)仅修改类(class),而不是模块(module),因此参数必须是一个类。一旦你意识到自己在做什么,你有两个选项来全局地细化(refine)模块方法。由于Ruby具有开放的类(Open Classes),所以你可以简单地覆盖该方法。 — http://ruby-doc.org/core-2.1.1/doc/syntax/refinements_rdoc.html
▶ Math.exp 2
#⇒ 7.38905609893065
▶ module Math
▷   def self.exp arg
▷     Math::E ** arg
▷   end  
▷ end  
#⇒ :exp
▶ Math.exp 2
#⇒ 7.3890560989306495

无论您是否想要保存将被覆盖的方法的功能:
▶ module Math
▷   class << self
▷     alias_method :_____exp, :exp  
▷     def exp arg  
▷       _____exp arg    
▷     end  
▷   end  
▷ end  
#⇒ Math
▶ Math.exp 2
#⇒ 7.3890560989306495

请注意副作用。

1
那么有没有办法“改进”模块的方法? - Filip Bartuzi
目前还没有办法优化模块,正如我所链接的文档中明确说明的那样。 - Aleksei Matiushkin
可能有其他解决方案,而不仅仅是使用“refine”方法,这就是我正在寻找的。 - Filip Bartuzi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接