Ruby Language
method_missing
Suche…
Parameter
Parameter | Einzelheiten |
---|---|
Methode | Der Name der Methode, die aufgerufen wurde (im obigen Beispiel ist dies :say_moo , beachten Sie, dass dies ein Symbol ist. |
* args | Die Argumente, die an diese Methode übergeben wurden. Kann eine beliebige Zahl oder keine sein |
&Block | Der aufgerufene Block der Methode kann entweder ein do Block oder ein { } eingeschlossener Block sein |
Bemerkungen
Rufen Sie immer super an, ganz unten in dieser Funktion. Dies erspart den stillen Ausfall, wenn etwas aufgerufen wird und Sie keine Fehlermeldung erhalten.
Dieses method_missing verursacht beispielsweise Probleme:
class Animal
def method_missing(method, *args, &block)
say, speak = method.to_s.split("_")
if say == "say"
speak
end
end
end
=> Animal.new.foobar
=> nil # This should really be raising an error
method_missing
ist ein gutes Werkzeug, das Sie verwenden können, hat jedoch zwei Kosten, die Sie berücksichtigen sollten. Erstens ist method_missing
weniger effizient - Ruby muss die Klasse und alle ihre Vorfahren durchsuchen, bevor sie auf diesen Ansatz zurückgreifen kann. Diese Leistungsstrafe kann in einem einfachen Fall trivial sein, kann sich aber summieren. Zweitens ist dies eine Form der Meta-Programmierung, die über eine große Macht verfügt und dafür verantwortlich ist, dass die Implementierung sicher ist, böswillige Eingaben, unerwartete Eingaben usw. ordnungsgemäß verarbeitet.
Sie sollten auch respond_to_missing?
überschreiben respond_to_missing?
wie so:
class Animal
def respond_to_missing?(method, include_private = false)
method.to_s.start_with?("say_") || super
end
end
=> Animal.new.respond_to?(:say_moo) # => true
Aufrufe einer undefinierten Methode abfangen
class Animal
def method_missing(method, *args, &block)
"Cannot call #{method} on Animal"
end
end
=> Animal.new.say_moo
> "Cannot call say_moo on Animal"
Verwenden Sie die fehlende Methode
class Animal
def method_missing(method, *args, &block)
say, speak = method.to_s.split("_")
if say == "say"
speak
else
super
end
end
end
=> a = Animal.new
=> a.say_moo
=> "moo"
=> a.shout_moo
=> NoMethodError: undefined method `shout_moo'
Verwenden Sie mit Block
class Animal
def method_missing(method, *args, &block)
if method.to_s == 'say'
block.call
else
super
end
end
end
=> Animal.new.say{ 'moo' }
=> "moo"
Verwenden Sie mit dem Parameter
class Animal
def method_missing(method, *args, &block)
say, speak = method.to_s.split("_")
if say == "say" && speak
return speak.upcase if args.first == "shout"
speak
else
super
end
end
end
=> Animal.new.say_moo
=> "moo"
=> Animal.new.say_moo("shout")
=> "MOO"