Как улучшить модульный метод в Ruby?

Вы можете улучшить свой класс с помощью

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)


person Filip Bartuzi    schedule 20.08.2015    source источник


Ответы (2)


Этот фрагмент кода будет работать:

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 .

person lakesare    schedule 07.12.2015

Уточнения изменяют только классы, а не модули, поэтому аргументом должен быть класс.

- 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

Помните о побочных эффектах.

person Aleksei Matiushkin    schedule 20.08.2015
comment
Так есть ли способ уточнить метод модуля? - person Filip Bartuzi; 20.08.2015
comment
В настоящее время нет возможности доработать модули, как это четко указано в документации, на которую я ссылался. - person Aleksei Matiushkin; 20.08.2015
comment
Может быть другое решение, кроме использования точно refine метода, и это то, что я ищу - person Filip Bartuzi; 20.08.2015