ruby · level 3 · unit 4 · lesson 3
- meet it
- guess first
- your turn
- fix it
- nailed it
Tap a green word if you get lost.
meet it
catches calls to methods that do not exist.
When you call a method an object does not have, Ruby does not give up straight away. First it calls method_missing on that object, passing the method's name and its arguments, gathered by into an array. The built-in version raises NoMethodError. Write your own and you can answer instead, with a .
Rails uses this for finders such as find_by_city("York"). Check the name, handle only the pattern you expect, and hand everything else to super, the built-in version, so real typos still raise NoMethodError. Answering every call would hide bugs.
class Contacts
def initialize(people)
@people = people
end
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
end
book = Contacts.new([{ name: "Ana", city: "Leeds" }, { name: "Raj", city: "York" }])
p book.find_by_city("York")
p book.find_by_name("Ana") The name arrives as a symbol, such as :find_by_city, so to_s turns it into text you can trim.
guess first
One setting exists and one does not. What will this show?
Guess before you run it. Wrong guesses are how you learn, and nothing is marked.
class Settings
def initialize
@values = { theme: "dark", font: "serif" }
end
def method_missing(name, *args)
return super unless @values.key?(name)
@values[name]
end
end
settings = Settings.new
puts settings.theme
puts settings.colour
your turn
Your turn. Show a price in other currencies.
Choose a ticket price in pounds in the first blank. In the second blank, call the ghost method that shows the price in dollars.
fix it
The bug report blames the wrong method. Fix method_missing.
- The report blames
upcase, but the real mistake is asking forcolour. Why doescolournot fail? - This
method_missinganswers every name, even ones with no setting, and hands backnil. - Add
return super unless @values.key?(name)as the first line ofmethod_missing.
nailed it
you caught calls to methods that do not exist. :D
- Ruby calls
method_missingbefore raising NoMethodError. - Handle only the names you expect.
- Pass everything else to
super, so typos still fail loudly.
new words in your collection
- method_missing
- ghost method
- *args
This lesson isn’t saved. A free account remembers every lesson you finish.