Sto costruendo un plug-in che consentirà a uno sviluppatore di aggiungere varie funzionalità a una classe con una semplice dichiarazione nella definizione della classe (seguendo il normale modello act_as).Come posso impostare un hook per eseguire il codice alla fine di una definizione di classe Ruby?
Ad esempio, il codice che consumano il plugin potrebbe essere simile
class YourClass
consumes_my_plugin option1: :value1, specific_method_to_use: :your_method
end
La mia domanda si pone perché voglio errore di controllo che il valore previsto per il: specific_method_to_use parametro esiste come metodo, ma il codice modo è tipicamente organizzato e caricato, il metodo non esiste ancora.
Il codice nel mio plug-in appare timidamente in questo modo:
module MyPlugin
extend ActiveSupport::Concern
module ClassMethods
def consumes_my_plugin(options = {})
raise ArgumentError.new("#{options[:specific_method_to_use]} is not defined") if options[:specific_method_to_use].present? && !self.respond_to?(options[:specific_method_to_use])
end
end
end
Questo potrebbe funzionare:
class YourClass
def your_method; true; end
consumes_my_plugin option1: :value1, specific_method_to_use: :your_method
end
Ma questo è come la maggior parte delle persone scrivere codice, e non sarebbe:
class YourClass
consumes_my_plugin option1: :value1, specific_method_to_use: :your_method
def your_method; true; end
end
Come posso fallire al tempo di caricamento di YourClass? Lo voglio errore allora, non in fase di esecuzione con un NoMethodError. Posso rinviare l'esecuzione della linea che solleva l'ArgumentError fino a quando l'intera classe non viene caricata, o fare qualcosa di più intelligente per ottenerlo?
può fare la verifica nel punto in cui si sarebbe invocato 'specific_method_to_use' invece di fare il check in tempo di caricamento della lezione? –
: specifico_method_to_use viene richiamato solo in fase di runtime, quindi anche se potrei sicuramente catturare il NoMethodError e fornire un messaggio costruttivo allo sviluppatore attorno ad esso, il bug verrebbe catturato solo in fase di runtime, non al momento del caricamento ... penso che quest'ultimo sia preferibile. – LikeMaBell
Il controllo che stai facendo usando 'self.respond_to?' Non controllerà il metodo di istanza 'YourClass # your_method'; cercherà il metodo singleton/class "YourClass.your_method'. Nella mia risposta l'ho modificato in "self.instance_methods.include?". Sentiti libero di cambiarlo in 'respond_to?'se ho frainteso la tua intenzione. –