Domanda

Stavo leggendo Ruby e ho imparato a conoscere il suo modello di mixin, ma non riuscivo a pensare a molte funzionalità di mixin utili (perché molto probabilmente non sono abituato a pensare in questo modo).Quindi mi chiedevo quali sarebbero dei buoni esempi di utile funzionalità Mixin?

Grazie

Modificare:Un po' di background.Vengo dal C++ e da altri linguaggi a oggetti, ma il mio dubbio qui è che Ruby dica che non eredita i mixin, ma continuo a vedere i mixin come ereditarietà multipla, quindi temo che sto cercando di classificarli troppo presto nella mia zona di comfort , e non capisco davvero cosa sia un mixin.

È stato utile?

Soluzione

Bene il solito esempio credo sia Persistenza

module Persistence
    def load sFileName
            puts "load code to read #{sFileName} contents into my_data"
    end
        def save sFileName
        puts "Uber code to persist #{@my_data} to #{sFileName}"
    end

end

class BrandNewClass
    include Persistence
    attr :my_data

        def data=(someData)
        @my_data = someData
    end
end

b = BrandNewClass.new
b.data = "My pwd"
b.save "MyFile.secret"
b.load "MyFile.secret"

Immaginate il modulo è stato scritto da un ninja Ruby, che persiste lo Stato della classe in un file.
Ora supponiamo che io scrivo una nuova classe di zecca, posso riutilizzare la funzionalità di persistenza mescolandolo nel dicendo include ModuleILike. Si può anche includere moduli a runtime. Ottengo caricare e salvare i metodi gratis semplicemente mescolando in. Questi metodi sono proprio come quelli che lei stesso ha scritto per la classe. Codice / Comportamento / Funzionalità-riutilizzo senza eredità!

Quindi quello che stai facendo è compreso metodi alla tabella di metodo per la classe (non letteralmente corretti ma chiudi).

Altri suggerimenti

Di solito sono utilizzati per aggiungere una qualche forma di funzionalità standard a una classe, senza dover ridefinire tutto. Probabilmente si può pensare di loro un po 'come le interfacce in Java, ma invece di definire un elenco di metodi che devono essere implementati, molti di loro sarà effettivamente essere implementata includendo il modulo.

Ci sono alcuni esempi nella libreria standard:

Singleton - Un modulo che può essere miscelato in ogni classe per renderlo un Singleton. Il metodo di inizializzazione è fatto privato, e un metodo di istanza aggiunto, che assicura che non v'è sempre e solo un esempio di quella classe nell'applicazione.

Paragonabile - Se si include questo modulo in una classe, che definisce il metodo <=>, che confronta l'istanza corrente con un altro oggetto e dice che è più grande, è abbastanza per fornire <, <=, ==,> =, > e mezzo? metodi.

Enumerable - Mescolando in questo modulo, e la definizione di un ogni metodo, si ottiene il supporto per tutti gli altri metodi correlati, come raccolta, iniettare, selezionare e rifiutare. Se è anche ottenuto il metodo <=>, allora sarà anche il supporto sorta, min e max.

DataMapper è anche un interessante esempio di cosa può essere fatto con una semplice istruzione include, prendendo una classe standard, e aggiungendo la capacità di persistere in un archivio dati.

In Ruby, la ragione per cui i Mixin non sono ereditarietà multipla è che la combinazione dei metodi di mixin è una cosa da fare una volta sola.Questo non sarebbe un grosso problema, tranne per il fatto che i moduli e le classi di Ruby sono aperti a modifiche.Ciò significa che se mescoli un modulo alla tua classe, aggiungi un metodo al modulo, il metodo non lo farà essere disponibile per la tua classe;dove se lo facessi nell'ordine opposto, lo farebbe.

È come ordinare un cono gelato.Se prendi confettini di cioccolato e pezzetti di caramello come mixin e te ne vai con il tuo cono, il tipo di cono gelato che hai non cambierà se qualcuno aggiunge confettini multicolori al contenitore dei confettini di cioccolato in gelateria.La tua classe, il cono gelato, non viene modificata quando lo è il modulo di miscelazione, il contenitore dei confettini.La prossima persona che utilizzerà quel modulo di mixin vedrà i cambiamenti.

Quando tu include un modulo in Ruby, chiama Module#append_features su quel modulo, che aggiunge una copia dei metodi di quel modulo all'include una volta.

L'ereditarietà multipla, a quanto ho capito, è più simile alla delega.Se la tua classe non sa come fare qualcosa, lo chiede ai suoi genitori.In un ambiente di classe aperta, i genitori di una classe potrebbero essere stati modificati dopo la creazione della classe.

È come una relazione genitore-figlio RL.Tua madre potrebbe aver imparato a fare il giocoliere dopo la tua nascita, ma se qualcuno ti chiede di fare il giocoliere e tu glielo chiedi:mostrarti come (copiarlo quando ne hai bisogno) o farlo per te (pura delega), allora lei sarà in grado a quel punto, anche se sei stato creato prima che lo fosse la sua capacità di destreggiarsi.

È possibile che tu possa modificare un modulo Ruby 'include' per agire più come un'ereditarietà multipla modificando Module#append_features per mantenere un elenco di includer e quindi aggiornarli utilizzando il file method_added callback, ma questo rappresenterebbe un grande cambiamento rispetto allo standard Ruby e potrebbe causare grossi problemi quando si lavora con altri codici.Potrebbe essere meglio creare un file Module#inherit metodo che ha chiamato include e ha gestito anche la delega.

Per quanto riguarda un esempio del mondo reale, Enumerable è fantastico.Se definisci #each e includere Enumerable nella tua classe, questo ti dà accesso a tutta una serie di iteratori, senza che tu debba codificarli tutti.

E 'in gran parte utilizzato come si potrebbe usare l'ereditarietà multipla in C ++ o interfacce di applicazione in Java / C #. Non sono sicuro di dove la vostra esperienza si trova, ma se avete fatto queste cose prima, mixins sono come li farebbe in Ruby. E 'un modo sistematizzato di iniettare funzionalità in classi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top