📖 Scenario: Imagine you are building a simple Ruby class that can respond to any method call by printing a message. This is useful when you want to catch all undefined method calls and handle them gracefully.
🎯 Goal: You will create a Ruby class that uses method_missing to catch all calls to undefined methods and print a message showing the method name and arguments.
📋 What You'll Learn
Create a class called CatchAll
Define a method_missing method inside the class
Make method_missing print the method name and any arguments passed
Create an instance of CatchAll and call an undefined method on it
Print the output of the undefined method call
💡 Why This Matters
🌍 Real World
Using <code>method_missing</code> helps create flexible Ruby classes that can handle unexpected method calls without errors, useful in dynamic APIs or proxy objects.
💼 Career
Understanding <code>method_missing</code> is important for Ruby developers working with metaprogramming, dynamic method handling, and building DSLs (domain-specific languages).
Progress0 / 4 steps
1
Create the CatchAll class
Create a class called CatchAll with no methods inside.
Ruby
Hint
Use the class keyword followed by CatchAll and end.
2
Add method_missing to catch undefined methods
Inside the CatchAll class, define a method called method_missing that takes two parameters: method_name and *args.
Ruby
Hint
Define def method_missing(method_name, *args) inside the class.
3
Print method name and arguments inside method_missing
Inside method_missing, write a puts statement that prints: "Called method: with arguments: " using string interpolation.
Ruby
Hint
Use puts with double quotes and #{} to insert variables. Use args.inspect to print arguments as an array.
4
Create instance and call undefined method
Create an instance called obj of CatchAll and call the undefined method hello with arguments "world" and 123. This should print the catch-all message.
Ruby
Hint
Create obj = CatchAll.new and call obj.hello("world", 123).
Practice
(1/5)
1.
What is the main purpose of the method_missing method in Ruby?
easy
A. To catch calls to methods that do not exist and handle them dynamically.
B. To define a method that always returns nil.
C. To automatically create getter and setter methods.
D. To override existing methods with new behavior.
Solution
Step 1: Understand what method_missing does
method_missing is called when an object receives a method call it does not have defined.
Step 2: Identify its purpose
It allows handling these unknown method calls dynamically, enabling flexible behavior.
Final Answer:
To catch calls to methods that do not exist and handle them dynamically. -> Option A
Quick Check:
method_missing catches unknown methods [OK]
Hint: Remember: method_missing handles calls to undefined methods [OK]
Common Mistakes:
Thinking method_missing defines new methods automatically
Which of the following is the correct syntax to define method_missing in a Ruby class?
class Example
# Your code here
end
easy
A. def method_missing(method_name)
puts "Unknown method: #{method_name}"
end
B. def method_missing(method_name, args)
puts "Unknown method: #{method_name} with args: #{args}"
end
C. def method_missing(method_name, *args)
puts "Unknown method: #{method_name} with args: #{args}"
end
D. def method_missing(*args)
puts "Unknown method called"
end
Solution
Step 1: Recall method_missing signature
The method receives the missing method's name as a symbol and any arguments as a splat array.
Step 2: Check each option's parameters
def method_missing(method_name, *args)
puts "Unknown method: #{method_name} with args: #{args}"
end correctly uses method_name, *args to capture method name and all arguments.
Final Answer:
def method_missing(method_name, *args)
puts "Unknown method: #{method_name} with args: #{args}"
end -> Option C
Quick Check:
Correct parameters = def method_missing(method_name, *args)
puts "Unknown method: #{method_name} with args: #{args}"
end [OK]
Hint: method_missing needs method name and splat args [OK]
Common Mistakes:
Forgetting the splat (*) before args
Using only one parameter for method_missing
Passing args without splat causing errors
3.
What will be the output of this Ruby code?
class CatchAll
def method_missing(name, *args)
"Called #{name} with #{args.join(', ')}"
end
end
obj = CatchAll.new
puts obj.hello('world')
medium
A. hello
B. Called hello with world
C. NoMethodError
D. Called method_missing with hello
Solution
Step 1: Understand method_missing behavior
The method_missing catches the call to hello which is undefined and returns a string with method name and arguments.
Step 2: Evaluate the output
Calling obj.hello('world') triggers method_missing with name :hello and args ['world'], so output is "Called hello with world".
Final Answer:
Called hello with world -> Option B
Quick Check:
method_missing output = Called hello with world [OK]
Hint: method_missing returns string with method name and args [OK]
Common Mistakes:
Expecting NoMethodError instead of method_missing output
Confusing method name symbol with string
Ignoring args passed to method_missing
4.
Identify the error in this Ruby class using method_missing:
class Test
def method_missing(name)
puts "Missing: #{name}"
end
end
Test.new.unknown_method(1, 2)
medium
A. method_missing should accept a splat argument for extra parameters.
B. method_missing must return a value, not puts.
C. method_missing cannot be defined in a class.
D. No error; code runs fine.
Solution
Step 1: Check method_missing parameters
The call unknown_method(1, 2) passes two arguments, but method_missing only accepts one parameter name.
Step 2: Identify the fix
To handle any number of arguments, method_missing must accept *args as a splat parameter.
Final Answer:
method_missing should accept a splat argument for extra parameters. -> Option A
Quick Check:
Missing splat args causes error [OK]
Hint: Add *args to method_missing to catch all parameters [OK]
Common Mistakes:
Ignoring extra arguments passed to missing method
Assuming puts return is enough
Thinking method_missing can't be defined in classes
5.
Given this class, what will obj.foo.bar(1) output?
class CatchAll
def method_missing(name, *args)
if name == :bar
"Handled bar with #{args[0]}"
else
self
end
end
end
obj = CatchAll.new
puts obj.foo.bar(1)
hard
A. NoMethodError for foo
B. Handled bar with nil
C. self
D. Handled bar with 1
Solution
Step 1: Trace obj.foo call
Calling obj.foo triggers method_missing with name=:foo, which returns self (the object itself).
Step 2: Trace .bar(1) call on returned self
Calling .bar(1) triggers method_missing with name=:bar and args [1], which returns "Handled bar with 1".