Tecnicamente, @ndn ha ragione, potrebbe essere chiamato dopo che la classe è stata valutata. Tuttavia, sembra che quello che vuoi è di convalidare che il metodo configure sia stato chiamato ad un certo punto all'interno della definizione del corpo della classe (questo permetterà anche a tutti i moduli che sono stati inclusi, di finire di valutare, quindi se un modulo include chiamate configura metodo, va tutto bene).
La soluzione più vicina che è venuta in mente per affrontare questa situazione può essere trovato qui:
https://github.com/jasonayre/trax_core/blob/master/lib/trax/core/abstract_methods.rb
Il codice di cui sopra è un'implementazione metodi astratta per rubino, che tecnicamente non è quello che stai chiedendo (stai parlando di chiamare il metodo, i metodi astratti riguardano il controllo che una sottoclasse lo ha definito), ma lo stesso trucco che ho usato potrebbe essere applicato.
Fondamentalmente, sto usando la libreria dei punti di traccia di Ruby per controllare che la definizione della classe colpisca, a quel punto spara un evento, controllo se il metodo è stato definito e lancia un errore se non lo è. Quindi, finché chiami configure da WITHIN nelle tue classi, una soluzione simile potrebbe funzionare per te. Qualcosa di simile (non testato):
module MustConfigure
extend ::ActiveSupport::Concern
module ClassMethods
def inherited(subklass)
super(subklass)
subklass.class_attribute :_configured_was_called
subklass._configured_was_called = false
trace = ::TracePoint.new(:end) do |tracepoint|
if tracepoint.self == subklass #modules also trace end we only care about the class end
trace.disable
raise NotImplementedError.new("Must call configure") unless subklass._configured_was_called
end
end
trace.enable
subklass
end
def configure(&block)
self._configured_was_called = true
#do your thing
end
end
end
class A
include MustConfigure
end
class B < A
configure do
#dowhatever
end
end
class C < B
#will blow up here
end
Oppure, si potrebbe provare a utilizzare il modulo InheritanceHooks dalla mia biblioteca e saltare la movimentazione tracepoint manuale:
class BaseClass
include::Trax::Core::InheritanceHooks
after_inherited do
raise NotImplementedError unless self._configure_was_called
end
end
nota, anche se sto usando questo modello in produzione al momento, e tutto funziona alla grande con la risonanza magnetica, perché tracepoint è una libreria creata per il debug, ci sono alcune limitazioni quando si utilizza jruby. (in questo momento si interrompe se non si passa il flag di debug di jruby) - Ho aperto un problema per un po 'di tempo cercando di ottenere il tracepoint aggiunto senza dover abilitare il debug in modo esplicito.
https://github.com/jruby/jruby/issues/3096
Quando deve essere generata un'eccezione? Quando il processo esce? Come fai a sapere che non sarà chiamato in futuro? – ndn
L'eccezione dovrebbe essere generata quando la classe B è stata definita. Ma hai un punto con * Come fai a sapere che non verrà chiamato in futuro? * – 23tux
Una classe può essere riaperta.Un modulo può essere incluso dopo che una classe è stata definita. – ndn