×

ruby · level 3 · unit 4 · lesson 4

  1. meet it
  2. guess first
  3. your turn
  4. fix it
  5. 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.