Ogni elemento in Ruby è un oggetto: credo di aver ripetuto questa frase almeno due volte in questo Ruby Diary. Direi che è arrivato il momento di capirne qualcosa di pià sugli oggetti... cosa ne dite?
Una delle prime difficoltà con le quali mi sono scontrato non appena mi sono avvicinato a Ruby ha riguardato il concetto di Modulo rispetto a quello di Classe.
Come insegnano i primi passi, nei quattro oggetti fondamentali sono compresi l'oggetto Module e l'oggetto Class, figlio di Module.
Ma qual è la differenza tra una classe ed un modulo?
Per banalizzare il concetto, la differenza fondamentale è che una classe è un modulo che può essere istanziato. Prendiamo ad esempio la classe File ed il modulo FileUtils.
Voi potete creare nuove istanze di File
, ad esempio
doc = File.new("document.doc") image = File.new("document/image.gif")
ma non potete creare una istanza di FileUtils
. Non esiste FileUtils.new()
così come non esiste un metodo del modulo FileUtils
che restituisca una sua istanza.
Più facilmente restituirà una istanza di un File
. E con questa affermazione ci avviciniamo al secondo orientamento che distingue moduli da classi.
Potete pensare ad un modulo come ad una cassetta degli attrezzi, ad un contenitore o ad una qualche raccolta di metodi che vi consente di lavorare su oggetti. Non è raro che ad un modulo corrisponda una classe che rappresenti le istanze "gestite" dal modulo.
Classi e moduli hanno comportamenti comuni. Come pensare diversamente, poiché Class < Module
(si legge Class estende Module) ne eredita anche metodi ed attributi.
Sia classi sia moduli possono quindi essere utilizzati per definire Namespace.
module Foo class Bar def initialize() // do something end end end bar = Foo::Bar.new()
class Foo class Bar def initialize() // do something end end end bar = Class::Bar.new()
Normalmente si tende ad utilizzare i moduli per i Namespace principali poiché difficilmente un Namespace ammette di avere delle istanze.
Ma sia classi sia moduli permettono di essere estesi? Questo ve lo lascio come compito a casa.
Come procedereste per testare rapidamente la soluzione?
I moduli, in Ruby, offrono anche un'eccellente alternativa per simulare ereditarietà multipla delle classi e realizzare classi modulari chiamate Mixin. Ma per questo dovrete aspettare un altro post!