Uno degli aspetti fondamentali di Ruby è la sua dinamicità , la possibilità di eseguire un binding dinamico di una classe ridefinendola runtime.
A mio avviso, questo è anche uno dei punti deboli che aprono le porte ad una possibile cattiva programmazione. Esagerare nella ridefinizione di una classe può creare problemi, molti problemi.
Se per esempio, per sbaglio, ridefinite un metodo di una classe core come String
, o peggio ancora Module
o Class
c'è il rischio di combinare un bel pasticcio e rendere il debug un incubo!
Anche se questo problema è apparentemente raro quando siete voi a programmare, potrebbe accadere se riutilizzate classi o librerire di altri. àˆ un attimo: un momento prima tutto funziona, dopo inizia a funzionare ad intermittenza. Cosa è successo? Nulla, non ho cambiato una virgola... a parte... includere quella libreria esterna che prepara il caffé. Ma prepara il caffé, cosa c'entra con la mia gestione delle stringhe non funzionante?!?
Semplice, la libreria caffettiera per qualche oscuro motivo ridefinisce il metodo gsub
ed ecco che tutto comincia a non funzionare più!
Attenzione quindi a non abusare di questa possibilità . NON ridefinite mai metodi esistenti di classi core, eventualmente create metodi aggiuntivi.
Utilizzate Namespace per prevenire la sovrascrittura accidentale di una classe e prestate molta attenzione alle proprietà di una classe quando la ereditate o la estendete.
Infine, non dimenticate che potete sempre usare i metodi di Module per verificare se un metodo è già esistente. Ad esempio:
module A def method1() end end class B def method2() end end class C < B include A def method3() end end A.method_defined? :method1 #=> true C.method_defined? "method1" #=> true C.method_defined? "method2" #=> true C.method_defined? "method3" #=> true C.method_defined? "method4" #=> false