Sök…


parametrar

Parameter detaljer
metod Namnet på metoden som har kallats (i exemplet ovan är detta :say_moo , notera att det här är en symbol.
* args Argumenten som skickats till denna metod. Kan vara valfritt nummer eller ingen
&blockera Blocket för den metod som kallas, detta kan antingen vara ett do block eller ett { } slutet block

Anmärkningar

Ring alltid super, längst ner i den här funktionen. Detta sparar tyst misslyckande när något anropas och du inte får något fel.

Till exempel kommer den här metoden att missa orsaka problem:

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 är ett bra verktyg att använda när det är lämpligt, men har två kostnader du bör tänka på. Först, method_missing är mindre effektiv - rubin måste söka i klassen och alla dess förfäder innan den kan falla tillbaka på denna metod; denna prestationsstraff kan vara trivial i ett enkelt fall, men kan lägga till. För det andra är detta en form av metaprogrammering som har stor makt som har ansvaret för att se till att implementeringen är säker, hanterar skadliga insatser, oväntade ingångar och så vidare.

Du bör också åsidosätta respond_to_missing? såhär:

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

Att fånga samtal till en odefinierad metod

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"

Med hjälp av den saknade metoden

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'

Använd med 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" 

Använd med 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" 


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow