Ich baue ein Plugin, das es einem Entwickler ermöglicht, einer Klasse verschiedene Funktionen mit einer einfachen Deklaration in der Klassendefinition hinzuzufügen (nach dem normalen Muster acts_as).Wie kann ich einen Hook festlegen, um Code am Ende einer Ruby-Klassendefinition auszuführen?
Zum Beispiel Code, um das Plugin raubend könnte so aussehen
class YourClass
consumes_my_plugin option1: :value1, specific_method_to_use: :your_method
end
Meine Frage stellt sich, weil ich überprüfen, um Fehler möchten, dass der bereitgestellte Wert für die: specific_method_to_use Parameter als Methode existiert, aber die Art und Weise Code typischerweise organisiert und geladen, existiert die Methode noch nicht.
Der Code in meinem Plugin sieht versuchsweise wie folgt aus:
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
Dies funktionieren würde:
class YourClass
def your_method; true; end
consumes_my_plugin option1: :value1, specific_method_to_use: :your_method
end
Aber das ist, wie die meisten Leute Code zu schreiben, und es wäre nicht:
class YourClass
consumes_my_plugin option1: :value1, specific_method_to_use: :your_method
def your_method; true; end
end
Wie kann ich bei YourClass Ladezeit fehlschlagen? Ich möchte es dann auf Fehler setzen, nicht zur Laufzeit mit einem NoMethodError. Kann ich die Ausführung der Zeile, die den ArgumentError auslöst, verschieben, bis die gesamte Klasse geladen ist, oder etwas anderes machen, um das zu erreichen?
können Sie die Prüfung an der Stelle tun, wo Sie aufgerufen haben würde 'specific_method_to_use' anstatt die Prüfung in der Klassenladezeit zu machen? –
: specific_method_to_use wird nur zur Laufzeit aufgerufen, also konnte ich zwar den NoMethodError abfangen und konstruktive Nachrichten an den Entwickler senden, aber der Bug wurde nur zur Laufzeit und nicht zur Ladezeit erkannt ... Letzteres ist meiner Meinung nach vorzuziehen. – LikeMaBell
Die Überprüfung, die Sie mit 'self.respond_to?' Durchführen, wird nicht nach der Instanzmethode 'YourClass # your_method' suchen; Es wird nach der Singleton/Klassenmethode 'YourClass.your_method' gesucht. In meiner Antwort änderte ich es zu 'self.instance_methods.include?'. Fühlen Sie sich frei, es zurück zu 'reagieren_to?"Wenn ich deine Absicht falsch verstanden habe. –