La famosa libreria alla quale sto lavorando ha una necessità : creare una classe base Result
, astratta, con i metodi e le proprietà base parte di ogni risultato. L'oggetto Result a sua volta dovrà avere una implementazione concreta in una sottoclasse, ad esempio ProductResult
.
In una normale classe in PHP 5 o in Java sarei partito a razzo nella creazione di una classe Result astratta.
Così, tranquillo come non mai, inizio a cercare online un po' di documentazione sulla dichiarazione delle classi astratte in Ruby. Gulp... non esistono! Eh già , Ruby non prevede la definizione di classi astratte.
Oibho! Datemi 5 minuti, ci vuole un caffè, mi è appena crollato il mondo addosso.
Ok, i 5 minuti sono passati e mi rimetto all'opera. Cos'è una classe astratta? Di fatto, una classe astratta ha la particolarità di non poter essere istanziata autonomamente ma deve per forza essere estesa. Lo stesso vale per un metodo astratto.
A questo punto c'è una alternativa per Ruby. Abbiamo visto che alla creazione di una nuova istanza viene chiamato il metodo initialize()
dunque, per creare una classe astratta, posso fare in modo che la mia classe restituisca un errore quando viene istanziata.
class AbstractClass def initialize() raise NotImplementedError, "#{self.class} is an abstract class" end def other_method() # ... end end
L'eccezione NotImplementedError restituita è presente nella core library di Ruby. A questo punto, la nostra classe dovrà estendere quella astratta sovrascrivendo il metodo initialize().
class RealClass < AbstractClass def initialize() # do something end def my_method() # do something end end
L'oggetto RealClass
conterrà i metodi definiti nella classe RealClass
ed erediterà correttamente quelli definiti in AbstractClass
. Questo sistema è in realtà un workaround, ma funziona abbastanza egregiamente.
Esiste un bug in questa implementazione, sapreste individuarlo? Vi fornisco un indizio.
I più geek sapranno senz'altro astrarre la procedura in un comodo Modulo da utilizzare come Mixin.
Per chi preferisce attendere approfitto per comunicare che appena sarà un po' meglio organizzato metterà a disposizione una serie di librerie Ruby sviluppate e testate.