Stats

62 Contributors: 6
Sunday, September 11, 2016
Licensed under: CC-BY-SA

Not affiliated with Stack Overflow
Rip Tutorial: info@zzzprojects.com

Download eBook

method_missing

Download ruby eBook

Parameters

ParameterDetails
methodThe name of the method that has been called (in the above example this is :say_moo, note that this is a symbol.
*argsThe arguments passed in to this method. Can be any number, or none
&blockThe block of the method called, this can either be a do block, or a { } enclosed block

Remarks

Always call super, at the bottom of this function. This saves silent failure when something is called and you don't get an error.

For example, this method_missing is going to cause problems:

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 a good tool to use when appropriate, but has two costs you should consider. First, method_missing is less efficient -- ruby must search the class and all of its ancestors before it can fall back on this approach; this performance penalty may be trivial in a simple case, but can add up. Second and more broadly, this is a form of meta-programming that has great power that comes with responsibility to ensure that the implementation is secure, properly handles malicious inputs, unexpected inputs, and so on.

You should also override respond_to_missing? like 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

Related Examples