Bird
Raised Fist0
Rubyprogramming~20 mins

Why metaprogramming is powerful in Ruby - Challenge Your Understanding

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Ruby Metaprogramming Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output of this Ruby metaprogramming code?

Consider this Ruby code that uses define_method to create methods dynamically. What will it print?

Ruby
class Greeter
  [:hello, :goodbye].each do |method_name|
    define_method(method_name) do |name|
      "#{method_name.to_s.capitalize}, #{name}!"
    end
  end
end

g = Greeter.new
puts g.hello("Alice")
puts g.goodbye("Bob")
AHello, Alice!\nGoodbye, Bob!
Bhello, Alice!\ngoodbye, Bob!
CError: undefined method
DHELLO, Alice!\nGOODBYE, Bob!
Attempts:
2 left
💡 Hint

Look at how define_method uses the symbol and string interpolation.

🧠 Conceptual
intermediate
1:30remaining
Why is metaprogramming powerful in Ruby?

Which of these best explains why metaprogramming is powerful in Ruby?

AIt restricts the use of dynamic variables to prevent bugs.
BIt forces all methods to be defined before the program runs, improving performance.
CIt allows programs to write or modify code during runtime, enabling flexible and DRY designs.
DIt automatically converts Ruby code to machine code for faster execution.
Attempts:
2 left
💡 Hint

Think about what it means to change code while the program is running.

🔧 Debug
advanced
2:30remaining
Find the error in this metaprogramming code

This Ruby code tries to create getter methods dynamically but raises an error. What is the cause?

Ruby
class Person
  [:name, :age].each do |attr|
    define_method(attr) do
      @attr
    end
  end
end

p = Person.new
p.name
AThe instance variable should be @name or @age, not @attr.
BYou cannot use define_method inside a class.
CThe array [:name, :age] should be strings, not symbols.
DMissing parentheses in define_method call.
Attempts:
2 left
💡 Hint

Check what @attr means inside the method.

📝 Syntax
advanced
1:30remaining
Which option correctly defines a method dynamically with parameters?

Which Ruby code correctly defines a method greet that takes a name parameter and returns a greeting?

Adefine_method(:greet) |name| { "Hello, #{name}!" }
Bdefine_method greet(name) { "Hello, #{name}!" }
Cdefine_method(:greet) do name; "Hello, #{name}!" end
Ddefine_method(:greet) { |name| "Hello, #{name}!" }
Attempts:
2 left
💡 Hint

Remember the syntax for define_method with a block and parameters.

🚀 Application
expert
3:00remaining
What is the output of this Ruby metaprogramming example?

This Ruby code uses method_missing to handle undefined methods. What will it print?

Ruby
class Dynamic
  def method_missing(name, *args)
    if name.to_s.start_with?("say_")
      word = name.to_s.split("_")[1]
      "You said: #{word} with args: #{args.join(", ")}"
    else
      super
    end
  end
end

d = Dynamic.new
puts d.say_hello("world")
puts d.say_goodbye("everyone")
puts d.unknown_method
AYou said: say_hello with args: world\nYou said: say_goodbye with args: everyone\nNoMethodError
BYou said: hello with args: world\nYou said: goodbye with args: everyone\nNoMethodError
CNoMethodError\nNoMethodError\nNoMethodError
DYou said: hello with args: world\nYou said: goodbye with args: everyone\nYou said: unknown with args:
Attempts:
2 left
💡 Hint

Look at how method_missing handles method names starting with say_.

Practice

(1/5)
1. What is the main benefit of metaprogramming in Ruby?
easy
A. It makes Ruby code run faster by compiling to machine code
B. It allows programs to create or modify code while running
C. It prevents errors by checking syntax before running
D. It automatically formats code for better readability

Solution

  1. Step 1: Understand metaprogramming concept

    Metaprogramming means writing code that can write or change other code during program execution.
  2. Step 2: Identify the main benefit

    This ability makes programs flexible and dynamic, allowing changes without rewriting code.
  3. Final Answer:

    It allows programs to create or modify code while running -> Option B
  4. Quick Check:

    Metaprogramming = dynamic code creation [OK]
Hint: Metaprogramming means code that writes or changes code [OK]
Common Mistakes:
  • Confusing metaprogramming with faster execution
  • Thinking it only formats or checks code
  • Believing it prevents all runtime errors
2. Which Ruby syntax correctly defines a method dynamically using metaprogramming?
easy
A. create_method(:greet) -> puts 'Hello'
B. def_method :greet { puts 'Hello' }
C. method_define(:greet) do puts 'Hello' end
D. define_method(:greet) { puts 'Hello' }

Solution

  1. Step 1: Recall Ruby's dynamic method definition syntax

    Ruby uses define_method to create methods at runtime.
  2. Step 2: Match correct syntax

    define_method(:greet) { puts 'Hello' } uses define_method(:greet) { puts 'Hello' }, which is valid Ruby syntax.
  3. Final Answer:

    define_method(:greet) { puts 'Hello' } -> Option D
  4. Quick Check:

    define_method = dynamic method creation [OK]
Hint: Use define_method(:name) { ... } to create methods dynamically [OK]
Common Mistakes:
  • Using incorrect method names like def_method
  • Wrong block syntax or missing do/end
  • Confusing method creation with method calls
3. What will be the output of this Ruby code?
class Person
  def self.create_attr(name)
    define_method(name) { @attributes ||= {}; @attributes[name] }
    define_method("#{name}=") { |value| @attributes ||= {}; @attributes[name] = value }
  end

  create_attr :age
end

p = Person.new
p.age = 30
puts p.age
medium
A. 30
B. nil
C. Error: undefined method
D. 0

Solution

  1. Step 1: Understand dynamic attribute creation

    The class method create_attr defines getter and setter methods for the given attribute name using metaprogramming.
  2. Step 2: Trace code execution

    After calling create_attr :age, the instance has age and age= methods. Setting p.age = 30 stores 30 in @attributes[:age]. Then puts p.age outputs 30.
  3. Final Answer:

    30 -> Option A
  4. Quick Check:

    Dynamic getter/setter works = 30 output [OK]
Hint: Dynamic methods store and retrieve values correctly [OK]
Common Mistakes:
  • Expecting nil because @attributes is not initialized outside methods
  • Thinking method missing error will occur
  • Confusing instance variables with local variables
4. Identify the error in this Ruby metaprogramming code:
class Calculator
  def self.add_method(name, &block)
    define_method(name, &block)
  end

  add_method(:sum) do |a, b|
    a + b
  end
end

calc = Calculator.new
puts calc.sum(2, 3)
medium
A. Cannot call define_method inside a class method without instance context
B. Block syntax is incorrect for define_method
C. sum method requires three arguments, but two given
D. No error, code runs and outputs 5

Solution

  1. Step 1: Analyze the metaprogramming usage

    The class method add_method tries to call define_method directly, but define_method is a private instance method of Module, not available in the class method context.
  2. Step 2: Identify the error

    Calling define_method inside a class method without proper context causes an error.
  3. Final Answer:

    Cannot call define_method inside a class method without instance context -> Option A
  4. Quick Check:

    define_method must be called on class/module context, not inside class method directly [OK]
Hint: Use class_eval or define_method on self to define methods inside class methods [OK]
Common Mistakes:
  • Misunderstanding that define_method requires instance context
  • Thinking block syntax is wrong for define_method
  • Believing argument count mismatch
5. How can metaprogramming help reduce repeated code when creating multiple similar methods in Ruby?
hard
A. By using global variables to store method names
B. By manually writing each method with similar code
C. By dynamically defining methods based on a list of names
D. By disabling method creation to avoid repetition

Solution

  1. Step 1: Understand the problem of repeated code

    Writing many similar methods manually causes repetition and is hard to maintain.
  2. Step 2: Use metaprogramming to define methods dynamically

    Metaprogramming lets you loop over a list of method names and create each method automatically, reducing repetition.
  3. Final Answer:

    By dynamically defining methods based on a list of names -> Option C
  4. Quick Check:

    Dynamic method creation reduces repetition [OK]
Hint: Loop over names and define methods dynamically [OK]
Common Mistakes:
  • Thinking manual method writing is better
  • Using global variables incorrectly
  • Believing disabling methods helps repetition
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard