Singleton Class

Vedi tutte le pagine e le modifiche recenti o scarica i sorgenti nella pagina


(Questa spiegazione è stata data da Guy Decoux,su comp.lang.ruby/ruby-talk. Viene qui riportata in italiano sperando sia utile a chi vuole capire meglio ruby. L’intero thread può essere letto qui La notazione per indicare i metodi è quella comune : Classe::metodo_di_classe() e Classe#metodo_di_istanza().)

Ruby ha solo degli oggetti, cio’ significa che una classe e’ un oggetto e come ogni oggetto ha una classe (Class) dove sono definiti i suoi metodi.

Cio’ significa che, ad esempio, il metodo ::new() e’ definito nella classe Class, ed e’ una cosa del genere
   class Class
      def new(*args, &block)
         obj = allocate
         obj.send(:initialize, *args, &block)
         obj
      end
   end
quel metodo allocate() e’ il metodo della classe Class che serve ad, appunto, allocare un certo spazio di memoria trasformandolo in un oggetto

Cio’ funziona perfettamente, ma e’ facile vedere che esiste un problema. Se e’ stato semplice definire ::new(), sarebbe piu’ arduo definire ::allocate() nello stesso modo, poiche’ Array::allocate() e’ completamente differente da Hash::allocate() e non sarebbe bello definire un metodo Class#allocate() come un enorme switch e cambiarlo ogni volta che viene introdotta una nuova classe.

Un ulteriore problema si presenta nel caso si voglia definire un metodo File::open(), che possa accettare in input un blocco. Non e’ possibile definire tale metodo in Class (come Class#open()) poiche’ cio’ significherebbe definire anche Array::open(), Hash::open() e ovviamente non vogliamo una cosa simile.

Per risolvere questi due problemi, ruby associa ad ogni classe un oggetto e quando cerca un metodo di classe cerca prima in questo oggetto, e poi in Class.

Ora ruby puo’ funzionare, perche’ Ma una classe e’ un po’ speciale poiche’ esiste l’ereditarieta’ e quando viene scritto
    class A < Array
    end
Vogliamo riusare, per A, il metodo ::allocate() che e’ stato definito nell’oggetto speciale associato con Array cio’ significa che per quell’oggetto speciale, associato con una class, si vuole

esiste un oggetto che e perfetto per questo scopo, ed e’ esattamente una classe, e dato che questa classe sara’ sempre associata con un solo altro oggetto viene detta “singleton class, classe singolare.

Per finire, cio’ ci da’ questo: (dove (A) e’ la singleton class associata con A)
    Class  <  Module  <  Object
   (Class) < (Module) < (Object) < Class

      A    <  Array  <  Object 
     (A)   < (Array) < (Object)
E questo e’ lo schema che si trova nel file object.c Ora, al principio, abbiamo detto che una classe e’ un oggetto ed abbiamo introdotto la singleton class. Cio’ significa poter associare una classe singolare ad ogni oggetto, e facendo cio’ ottenere dei metodi specifici per quell’oggetto, ad esempio
   a = []
   class << a
      def tt
      end
   end
Quando ruby dovra’ cercare un metodo in a, cerchera’ prima nella sua classe singolare e poi nella sua classe.

Guy Decoux

Updated on December 24, 2008 11:47 by Andrea Fazzi (80.117.213.34)