Ruby Respond to Missing
The intermediate course answered unknown calls with method_missing. This lesson makes existence checks agree with that fallback, so a program can trust the answer it gets.
A fallback that respond_to? misses
Announcer answers cheer through method_missing. The respond_to? line still says false, because nothing told it about the fallback.
class Announcer
def method_missing(name, *args)
if name == :cheer
puts "Cheer called"
else
super
end
end
end
announcer = Announcer.new
announcer.cheer
puts announcer.respond_to?(:cheer)respond_to_missing? makes it honest
respond_to_missing? answers true for cheer and passes every other name to super. respond_to? now matches what the fallback can do.
class Announcer
def method_missing(name, *args)
if name == :cheer
puts "Cheer called"
else
super
end
end
def respond_to_missing?(name, include_private = false)
name == :cheer || super
end
end
announcer = Announcer.new
puts announcer.respond_to?(:cheer)
puts announcer.respond_to?(:sing)method builds a real Method
method asks for cheer and gets a Method object back. Calling that object runs the fallback, and its class prints as Method.
class Announcer
def method_missing(name, *args)
if name == :cheer
puts "Cheer called"
else
super
end
end
def respond_to_missing?(name, include_private = false)
name == :cheer || super
end
end
announcer = Announcer.new
action = announcer.method(:cheer)
action.call
puts action.classExample
class Greeter
def method_missing(name, *args)
if name.to_s.start_with?("hello_")
language = name.to_s.sub("hello_", "")
puts "Hello in #{language}"
else
super
end
end
def respond_to_missing?(name, include_private = false)
name.to_s.start_with?("hello_") || super
end
end
greeter = Greeter.new
puts greeter.respond_to?(:hello_french)
puts greeter.respond_to?(:goodbye_french)
greeter.hello_french
action = greeter.method(:hello_spanish)
action.callKey points
- method_missing can answer a call that respond_to? still reports as missing.
- respond_to_missing? tells respond_to? which fallback names are real.
- A name the fallback handles answers true from respond_to?.
- A name the fallback rejects still answers false from respond_to?.
- method builds a real Method object for a name the fallback handles.
- Calling that Method object runs the fallback with the stored name.
In this example, Greeter answers any name that starts with hello_ through method_missing. respond_to_missing? uses the same check, so respond_to? agrees with the fallback. method builds a Method for hello_spanish, and calling it greets in spanish.
Note
respond_to_missing? receives the name and an include_private flag.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
What does respond_to_missing? do for a class with method_missing?