Ruby Language
method_missing
Recherche…
Paramètres
Paramètre | Détails |
---|---|
méthode | Le nom de la méthode qui a été appelée (dans l'exemple ci-dessus, c'est :say_moo , notez qu'il s'agit d'un symbole. |
* args | Les arguments transmis à cette méthode. Peut être n'importe quel nombre, ou aucun |
&bloc | Le bloc de la méthode appelée, il peut s'agir d'un bloc do ou d'un bloc { } |
Remarques
Appelez toujours super, au bas de cette fonction. Cela évite les pannes silencieuses lorsque quelque chose est appelé et que vous n'obtenez pas d'erreur.
Par exemple, cette méthode_missing va causer des problèmes:
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
est un bon outil à utiliser lorsque cela est approprié, mais vous devez tenir compte de deux coûts. Premièrement, method_missing
est moins efficace - ruby doit rechercher la classe et tous ses ancêtres avant de pouvoir method_missing
cette approche; Cette pénalité de performance peut être triviale dans un cas simple, mais peut s’ajouter. Deuxièmement et plus largement, il s’agit d’une forme de méta-programmation dotée d’une grande puissance qui implique la responsabilité de garantir la sécurité de l’implémentation, de gérer correctement les entrées malveillantes, les entrées inattendues, etc.
Vous devriez également écraser respond_to_missing?
ainsi:
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
Attraper des appels à une méthode non définie
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"
Utiliser la méthode manquante
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'
Utiliser avec bloc
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"
Utiliser avec paramètre
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"