Ruby ha già diversi built-in callbacks. C'è un richiamo per questo caso? Un po 'come method_added, ma per le classi (o costanti) all'interno di un modulo, invece dei metodi di istanza all'interno di una classe.Chiamata per le classi definite all'interno di un modulo
risposta
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
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!"
È 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. –
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à. –