Ruby Language
method_missing
Zoeken…
parameters
Parameter | Details |
---|---|
methode | De naam van de methode die is aangeroepen (in het bovenstaande voorbeeld is dit :say_moo , merk op dat dit een symbool is. |
* args | De argumenten zijn doorgegeven aan deze methode. Kan elk getal zijn, of geen |
&blok | Het blok van de methode, dit kan een do blok zijn of een { } omsloten blok |
Opmerkingen
Roep altijd super op onderaan deze functie. Dit bespaart een stille storing wanneer er iets wordt aangeroepen en u geen foutmelding krijgt.
Deze methode zal bijvoorbeeld problemen veroorzaken:
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
is een goed hulpmiddel om te gebruiken wanneer van toepassing, maar heeft twee kosten die u moet overwegen. Ten eerste is method_missing
minder efficiënt - robijn moet de klasse en al zijn voorouders doorzoeken voordat het op deze aanpak kan terugvallen; deze prestatieboete kan in een eenvoudig geval triviaal zijn, maar kan oplopen. Ten tweede en meer in het algemeen, is dit een vorm van metaprogrammering die een grote kracht heeft, die gepaard gaat met verantwoordelijkheid om ervoor te zorgen dat de implementatie veilig is, goed omgaat met kwaadaardige invoer, onverwachte invoer, enzovoort.
Je moet ook respond_to_missing?
overschrijven respond_to_missing?
zoals zo:
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
Oproepen vangen naar een ongedefinieerde methode
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"
Gebruik de ontbrekende 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'
Gebruik met blok
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"
Gebruik met 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"