如何在 Ruby 中优化模块方法?
How to refine module method in Ruby?
您可以使用
优化您的 class
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)
Refinements only modify classes, not modules so the argument must be a class.
—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
请注意副作用。
这段代码可以工作:
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 上定义实例方法。
您可以使用
优化您的 classmodule 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)
Refinements only modify classes, not modules so the argument must be a class.
—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
请注意副作用。
这段代码可以工作:
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 上定义实例方法。