Ruby Method Missing
method_missing answers a call that an object does not know. Ruby hands the unknown name to this method instead of stopping at once.
Answer any name
The Echo class defines no alpha or beta method. method_missing answers both calls with the name it received.
class Echo
def method_missing(name, *args)
"You asked for #{name}"
end
def respond_to_missing?(name, include_private = false)
true
end
end
echo = Echo.new
puts echo.alpha
puts echo.beta
puts echo.respond_to? :gammaA settings object
A settings object stores its values in a hash. method_missing looks the name up and answers with a plain line for names it does not hold.
class Settings
def initialize
@values = { theme: "dark", size: "large" }
end
def method_missing(name, *args)
if @values.key? name
@values[name]
else
"Unknown setting #{name}"
end
end
def respond_to_missing?(name, include_private = false)
@values.key? name
end
end
settings = Settings.new
puts settings.theme
puts settings.size
puts settings.color
puts settings.respond_to? :theme
puts settings.respond_to? :colorExample
class Recorder
attr_reader :calls
def initialize
@calls = []
end
def method_missing(name, *args)
@calls << name
"#{name} recorded"
end
def respond_to_missing?(name, include_private = false)
true
end
end
recorder = Recorder.new
puts recorder.jump
puts recorder.run
p recorder.callsKey points
- Ruby calls method_missing when a method call finds no matching method.
- The first argument is the unknown name as a symbol.
- Extra call arguments arrive after the name.
- respond_to_missing? keeps respond_to? honest for those names.
- A careful method_missing still answers unknown names in a planned way.
In this example, the Recorder class defines no jump or run method. method_missing stores each unknown name in an array and answers with a line. The final line shows both names were kept.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
What does method_missing receive first?