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

Posted

技术标签:

【中文标题】如何在 Ruby 中优化模块方法?【英文标题】:How to refine module method in Ruby? 【发布时间】:2015-11-13 22:09:15 【问题描述】:

您可以使用

优化您的课程
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: wrong argument type Module (expected Class)

【问题讨论】:

【参考方案1】:

这段代码可以工作:

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是equivalent在其#singleton_class上定义一个实例方法。

【讨论】:

【参考方案2】:

细化只修改类,而不是模块,所以参数必须是一个类。

——http://ruby-doc.org/core-2.1.1/doc/syntax/refinements_rdoc.html

一旦您意识到自己在做什么,您就有两个选项可以在全局范围内优化模块方法。由于 ruby​​ 有开放类,您可以简单地覆盖该方法:

▶ 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

请注意副作用。

【讨论】:

那么有没有办法refine模块的方法? 目前没有办法细化模块,正如我链接的文档中明确指出的那样。 除了完全使用 refine 方法之外,可能还有其他解决方案,这就是我正在寻找的

以上是关于如何在 Ruby 中优化模块方法?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Ruby 的模块中定义类级宏?

ruby/rails:如何确定是不是包含模块?

ruby Ruby:如何创建一个包含相同方法的类和实例变体的模块

ruby:如何正确地要求(避免循环依赖)

如何在 ruby​​ 中引用子模块的“完整路径”?

Ruby:如何在模块加载到其父类中之前急切加载类内容