2015-08-20 26 views
7

Si può delimitare la classe conCome perfezionare il metodo del modulo in Ruby?

module RefinedString 
    refine String do 
    def to_boolean(text) 
    !!(text =~ /^(true|t|yes|y|1)$/i) 
    end 
    end 
end 

ma come perfezionare metodo di modulo? Questo :

module RefinedMath 
    refine Math do 
    def PI 
     22/7 
    end 
    end 
end 

solleva: TypeError: wrong argument type Module (expected Class)

risposta

1

perfezionamenti modificare solo classi, non moduli così l'argomento deve essere una classe.

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

Non appena si è consapevoli di quello che state facendo, si hanno due opzioni per affinare metodi del modulo a livello globale. Dal momento che ruby ​​ha classi aperte, si potrebbe semplicemente ignorare il metodo:

▶ Math.exp 2 
#⇒ 7.38905609893065 
▶ module Math 
▷ def self.exp arg 
▷  Math::E ** arg 
▷ end 
▷ end 
#⇒ :exp 
▶ Math.exp 2 
#⇒ 7.3890560989306495 

Se si desidera salvare la funzionalità del metodo da sovrascrivere:

▶ module Math 
▷ class << self 
▷  alias_method :_____exp, :exp 
▷  def exp arg 
▷  _____exp arg  
▷  end 
▷ end 
▷ end 
#⇒ Math 
▶ Math.exp 2 
#⇒ 7.3890560989306495 

Si prega di essere a conoscenza degli effetti collaterali.

+1

Quindi non v'è alcun modo per _refine_ il metodo del modulo? –

+0

Al momento non è possibile perfezionare i moduli, come indicato chiaramente nella documentazione che ho collegato. – mudasobwa

+0

Potrebbe esserci altra soluzione che usare esattamente il metodo 'refine' e questo è quello che sto cercando –

8

Ebbene, dal momento che la definizione di un modulo di #method è equivalent alla definizione di un metodo di istanza sulla sua #singleton_class, il seguente funziona:

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