ruby · level 3 · unit 4 · lesson 4
- meet it
- guess first
- your turn
- fix it
- nailed it
Tap a green word if you get lost.
meet it
makes ghost methods tell the truth.
Your contact book answers find_by_city, yet respond_to?(:find_by_city) says false. Ghost methods are invisible to the rest of Ruby, so code that checks before calling, as you did with public_send, would wrongly skip them.
Fix it with respond_to_missing?(name, include_private = false), using the same test as method_missing. The = false gives that parameter a . Ruby asks this method whenever respond_to? finds no real method. Now respond_to? tells the truth, and method(:find_by_name) can grab the ghost as an object to .call later.
class Contacts
PEOPLE = [{ name: "Ana", city: "Leeds" }, { name: "Raj", city: "York" }]
def method_missing(name, *args)
return super unless name.start_with?("find_by_")
field = name.to_s.sub("find_by_", "").to_sym
PEOPLE.find { |person| person[field] == args[0] }
end
def respond_to_missing?(name, include_private = false)
name.start_with?("find_by_") || super
end
end
book = Contacts.new
p book.respond_to?(:find_by_city)
p book.method(:find_by_name).call("Raj") If method_missing and respond_to_missing? ever use different tests, they will disagree, so change both together.
guess first
A ghost method with no respond_to_missing?. What will this show?
Guess before you run it. Wrong guesses are how you learn, and nothing is marked.
class Robot
def method_missing(name, *args)
return super unless name.start_with?("say_")
name.to_s.sub("say_", "").capitalize
end
end
robot = Robot.new
puts robot.say_hello
puts robot.respond_to?(:say_hello)
your turn
Your turn. Make the robot admit what it can say.
In the first blank, make respond_to_missing? use the same test as method_missing. In the second, choose any word for the robot to say.
fix it
method still cannot find the finder. Fix the class.
- The class answers
respond_to?, butmethodstill cannot find the ghost. Which hook doesmethodask? - Never replace
respond_to?itself. Ruby asks a different method whenever no real method exists. - Rename
respond_to?on line 8 torespond_to_missing?, then press run.
nailed it
your ghost methods tell the truth now. :D
- Write
respond_to_missing?whenever you writemethod_missing. - Use the same test in both, and fall back to
super. - Then
respond_to?andmethodcan see your ghost methods.
new words in your collection
- respond_to_missing?
- default value
This lesson isn’t saved. A free account remembers every lesson you finish.