2011-08-30 13 views
7

Vorrei una parte del mio modulo per estendere la classe String.Metaprogrammazione di base: estensione di una classe esistente utilizzando un modulo?

Questo non funziona

module MyModule 
    class String 
    def exclaim 
     self << "!!!!!" 
    end 
    end 
end 

include MyModule 

string = "this is a string" 
string.exclaim 

#=> NoMethodError 

Ma questo fa

module MyModule 
    def exclaim 
    self << "!!!!!" 
    end 
end 

class String 
    include MyModule 
end 

string = "this is a string" 
string.exclaim 

#=> "this is a string!!!!!" 

non voglio tutte le altre funzionalità di MyModule da abbandonati in String. Includerlo di nuovo al più alto livello sembra brutto. Sicuramente c'è un modo più ordinato per farlo?

risposta

25

Il metodo exclaim nel primo esempio viene definito all'interno di una classe denominata MyModule::String, che non ha nulla a che fare con la classe standard String.

Dentro il modulo, è possibile aprire il String classe standard (nel namespace globale) come questo:

module MyModule 
    class ::String 
    # ‘Multiple exclamation marks,’ he went on, shaking his head, 
    # ‘are a sure sign of a diseased mind.’ — Terry Pratchett, “Eric” 
    def exclaim 
     self << "!!!!" 
    end 
    end 
end 
+0

molto utile. grazie. – djb

+0

Invisito per la citazione nei commenti :-) – vijucat

1

io non sono sicuro che ho capito la tua domanda, ma perché farlo stringa non aprire in un file, dico exclaim.rb, e poi lo richiedono quando ne avete bisogno:

exclaim.rb

class String 
    def exclaim 
     self << "!!!!!" 
    end 
    end 

e poi

require "exclaim" 

"hello".exclaim 

Ma forse mi manca qualcosa?

+0

Sì, questo funziona. Ma la mia domanda è: la stringa può essere modificata direttamente da un modulo? – djb

+0

Oh ... ora ho la tua domanda. Fortunatamente, @Lars Haugseth ha fatto :) – lucapette

Problemi correlati