gaetanm gaetanm - 6 months ago 13
Ruby Question

Dynamically create a public method in a private method

I have code in a class that dynamically creates methods using

define_method
. I want to split it into two parts to make the code more understandable. I need to put a part of the code into a private block.

Here is how my code looks:

class Foo
["bar", "baz"].each do |method|
create_method(method)
end

private
def create_method(name)
define_method(name) do
puts "HELL"
end
end
end

Foo.new.bar



`create_method' for Foo:Class (NoMethodError)


I don't understand why it doesn't work.

Answer

There are several problems with your code. The error you are getting has absolutely nothing to do with private or public at all. The error message says that the method create_method cannot be found. There are two reasons for that:

  1. You are calling it before it is defined. You need to move the call to create_method after its definition.
  2. create_method is defined as an instance method, i.e. for calling it on instances of Foo, but you are calling it on Foo itself. You have to define it as a method somewhere in Foo's class (i.e. Class), one of its ancestors (e.g. Module), or Foo's singleton class.

I will define it as a singleton method of Foo here, but if the method really is as generic as you have showed in your example, then it probably rather belongs in Module instead.

class Foo
  class << self
    private
    def create_method(name)
      define_method(name) do
        puts "HELL"
      end
    end
  end

  ["bar", "baz"].each do |method|
     create_method(method)
  end
end

Foo.new.bar
# HELL
Comments