hoffm
hoffm

Reputation: 2436

Construct a Ruby object that returns the names of methods called on it

I want to construct a Ruby object that has the following property: For any method name, when that method name is passed to the object, the return value is the method name as a string.

Here is an attempt that has a few problems:

class Echo < BasicObject
  def self.method_missing(the_method)
    the_method.to_s
  end
end

Echo responds to most method calls as desired:

> Echo.foo
 => "foo" 
> Echo.send("Hello world.")
=> "Hello world." 

But Echo inherits from BasicObject and so it responds in the normal way to its superclass' methods:

> Echo.to_s
=> "Echo"

How can I construct an object that always echoes back the messages its passed. (Bonus points if the solution doesn't require complex method lookups on every call.)

Upvotes: 1

Views: 81

Answers (1)

Bryan Mytko
Bryan Mytko

Reputation: 26

How about:

class Echo
  class << self
    def method_missing(the_method)
      the_method.to_s
    end

    methods.each do |name|
      define_method(name) do |*any|
        name.to_s
      end
    end
  end
end

Tests:

RSpec.describe Echo do
  it "returns a missing method as a string" do
    expect(described_class.some_method_that_doesnt_exist).
      to eq("some_method_that_doesnt_exist")
  end

  it "returns an existing method as a string" do
    expect(described_class.to_s).
      to eq("to_s")
  end
end

Upvotes: 1

Related Questions