metaprogramming/method_missing/method_missing.rb

tests/_examples/metaprogramming/method_missing/method_missing.rb in the metorex repository.

# method_missing: Intercept calls to undefined methods
# Demonstrates Ruby-style method_missing hook

# 1. Basic method_missing — dynamic attribute access
class DynamicRecord
  def initialize
    @attributes = {name: "Alice", age: 30, role: "engineer"}
  end

  def method_missing(name)
    if @attributes.has_key?(name)
      @attributes[name]
    else
      "unknown: #{name}"
    end
  end
end

puts "=== Dynamic Attribute Access ==="
record = DynamicRecord.new()
puts record.name()
puts record.age()
puts record.role()
puts record.email()

# 2. method_missing with arguments
class Ghost
  def method_missing(name, *args)
    puts "Called #{name} with #{args.length} arg(s)"
  end
end

puts ""
puts "=== Ghost Methods ==="
ghost = Ghost.new()
ghost.hello()
ghost.add(1, 2)
ghost.greet("Alice", "Bob", "Charlie")

# 3. method_missing with arguments used for computation
class FlexibleCalc
  def method_missing(name, *args)
    if name == :sum
      total = 0
      args.each do |n|
        total = total + n
      end
      total
    else
      "unknown operation: #{name}"
    end
  end
end

puts ""
puts "=== Flexible Calculator ==="
calc = FlexibleCalc.new()
puts calc.sum(1, 2, 3)
puts calc.sum(10, 20)
puts calc.multiply(2, 3)

# 4. method_missing does not intercept defined methods
class Selective
  def real_method
    "I am real"
  end

  def method_missing(name)
    "ghost: #{name}"
  end
end

puts ""
puts "=== Selective ==="
s = Selective.new()
puts s.real_method()
puts s.fake_method()

# 5. method_missing in subclass (inherited)
class Base
  def method_missing(name)
    "Base caught: #{name}"
  end
end

class Child < Base
end

puts ""
puts "=== Inherited method_missing ==="
c = Child.new()
puts c.anything()
puts c.whatever()

Output:

=== Dynamic Attribute Access ===
Alice
30
engineer
unknown: email

=== Ghost Methods ===
Called hello with 0 arg(s)
Called add with 2 arg(s)
Called greet with 3 arg(s)

=== Flexible Calculator ===
6
30
unknown operation: multiply

=== Selective ===
I am real
ghost: fake_method

=== Inherited method_missing ===
Base caught: anything
Base caught: whatever