Buscar..


Parámetros

Parámetro Detalles
método El nombre del método que se ha llamado (en el ejemplo anterior es :say_moo , tenga en cuenta que este es un símbolo.
* args Los argumentos pasaron a este método. Puede ser cualquier número, o ninguno
&bloquear El bloque del método llamado, puede ser un bloque do o un bloque encerrado { }

Observaciones

Siempre llama super, en la parte inferior de esta función. Esto guarda un fallo silencioso cuando se llama a algo y no recibe un error.

Por ejemplo, este method_missing va a causar problemas:

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 es una buena herramienta para usar cuando sea apropiado, pero tiene dos costos que debe considerar. Primero, method_missing es menos eficiente: Ruby debe buscar en la clase y en todos sus ancestros antes de poder recurrir a este enfoque. esta penalización de rendimiento puede ser trivial en un caso simple, pero puede sumar. En segundo lugar, y más ampliamente, esta es una forma de meta-programación que tiene un gran poder que viene con la responsabilidad de garantizar que la implementación sea segura, que maneje adecuadamente las entradas maliciosas, las entradas inesperadas, etc.

También deberías anular la respond_to_missing? al igual que:

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

Atrapar llamadas a un método indefinido

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"

Usando el método que falta

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'

Usar con bloque

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" 

Utilizar con parametro

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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow