2010-11-16 1 views

risposta

4

Per quanto ne so, non c'è nulla di esattamente come quello che stai descrivendo. Tuttavia, ecco come puoi crearne uno, usando Class::inherited.

module MyModule 
    def self.class_added(klass) 
    # ... handle it 
    end 
    class ::Class 
    alias_method :old_inherited, :inherited 
    def inherited(subclass) 
     MyModule.class_added(subclass) if /^MyModule::\w+/.match subclass.name 
     old_inherited(subclass) 
    end 
    end 
end 

module MyModule 
    # now add classes 
end 
+0

Sì, metodi di patch di Classe hanno le proprie questioni. In particolare, ereditato non verrà chiamato su alcuna classe che definisce il proprio callback e non chiama super. L'alternativa è di alterare l'albero della sintassi con parsetree (non per ora 1.9 in tutti i casi). Ma sembra che manchino i callback. Ho chiesto perché il post di Gregor è piuttosto vecchio e i documenti non menzionano tale funzionalità. –

1

Si potrebbe provare questo approccio, definendo un proprio metodo def_class:

module M 
    def self.const_missing(name) 
    const_set(name, Class.new) 
    end 

    def self.def_class(klass, &block) 
    class_added(klass.name) 
    klass.class_eval(&block) 
    end 
end 

module M 
    def self.class_added(klass) 
    puts "new class added: #{klass}" 
    end 

    def_class Hello do 
    def hello 
     puts "hello!" 
    end 
    end 
end 

h = M::Hello.new.hello #=> "hello!" 
+0

È un buon compromesso. Con l'hack dell'albero di analisi, è anche possibile farlo senza che gli utenti debbano cambiare i propri moduli. Ma gli hack degli alberi parse introdurranno un altro scopo. Oppure introdurre un altro metodo simile a un modulo personalizzato. Non perfetto. So che Matz non voleva aggiungere altre callback, ma alcune sono davvero carenti. –