Ruby fornisce un costrutto chiamatoModule che è un po ‘ come una classe sottile. All’inizio, gli sviluppatori di Ruby potrebbero guardare i moduli come un ” cassetto spazzatura” di codice che viene appena gettato in giro e utilizzato per organizzare i file, ma c’è un metodo per questa follia. La classe RubyClass eredita daModule e aggiunge cose come istanziazione, proprietà, ecc. Poiché Module è letteralmente un antenato di Class, ciò significa che i moduli possono essere trattati come classi in qualche modo.
La cosa più importante da capire è come funziona la catena degli antenati di Ruby. Come tutti i linguaggi OOP, Ruby supporta l’ereditarietà. Quando si eredita da una classe, la superclasse viene aggiunta alla catena antenato. È possibile visualizzare gli antenati di qualsiasi classe chiamando ancestors su di esso:
class Foo < BarendFoo.ancestors#=>
Come accennato, è possibile trovare Module nell’array Class.ancestors.
 Quando si include un modulo nella classe, il modulo viene aggiunto alla catena antenato della classe – proprio come una classe. Questo rende include solo una forma di ereditarietà, non c’è nulla di speciale.
module Barendclass Foo include BarendFoo.ancestors#=>
Tutti i metodi inBarvengono aggiunti aFoo come metodi di istanza. Poiché Bar è nella catena, puoi anche chiamare super da esso per chiamare i metodi sopra di esso nella catena, indipendentemente dal fatto che siano definiti su Moduli o Classi.
class Baz def hello p 'world' endendmodule Bar def hello p 'hello' super endendclass Foo < Baz include BarendFoo.new.hello#=> hello world
Anche seBarè un modulo,superrichiama ancora la catena e quindi viene chiamato ancheBaz#hello. Vale la pena notare che Bar viene aggiunto alla catena antenata di fronte a Baz. Quando un modulo è incluso, viene sempre aggiunto direttamente in cima alla sua classe inclusa. Questo può diventare confuso quando si aggiungono più moduli, poiché sono inclusi nell’ordine “inverso”:
class Foo include A include BendFoo.ancestors#=>
QuandoAè incluso, viene inserito direttamente sopraFoo. Ma quandoB è incluso, viene inserito anche direttamente sopraFoo, quindi finisce per atterrare prima diA.
include vs extend
include è abbastanza facile da capire, aggiunge i metodi del modulo come metodi di istanza alla sua classe inclusa. Puoi pensare aextend facendo la stessa cosa, ma aggiungendo invece i metodi come metodi di classe.
module Bar def hello p 'hello' endendclass Foo extend BarendFoo.hello # no .new!# => 'hello'
antepone
Oltre a includere/estendere, Ruby 2.0+ aggiunge il metodo prependprependè simile ainclude, ma inserisce invece il modulo prima della classe including nella catena di ereditarietà.
class Foo include Bar prepend BazendFoo.ancestors#=>
 In Ruby puoi riaprire qualsiasi classe e ridefinire i metodi su di essa-non sembra utile sovrascrivere i metodi su una classe usando un modulo anteposto invece di ridefinirli. Doveprepend è utile quando hai ancora bisogno dell’implementazione originale del metodo, perché i moduli anteposti possono sovrascrivere i metodi ma usano ancorasuper per chiamare l’implementazione originale.