在私有方法中动态创建公共方法

时间:2016-05-21 14:13:14

标签: ruby

我在一个使用define_method动态创建方法的类中有代码。我想将它分成两部分,以使代码更容易理解。我需要将部分代码放入私有块中。

以下是我的代码的外观:

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)

我不明白为什么它不起作用。

4 个答案:

答案 0 :(得分:1)

您的代码存在一些问题。您获得的错误与privatepublic完全无关。错误消息指出无法找到方法create_method。这有两个原因:

  1. 您在定义之前调用它。您需要在定义之后将呼叫转移到create_method
  2. create_method被定义为实例方法,即在Foo实例上调用它,但您在Foo本身上调用它。您必须将其定义为Foo的类(即Class)中的某个方法,其中一个祖先(例如Module)或Foo& #39; s singleton class。
  3. 我会在这里将它定义为Foo的单例方法,但是如果该方法确实如您在示例中所示的那样通用,那么它可能宁可属于Module

    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
    

答案 1 :(得分:0)

不确定你出了什么问题,但这似乎对我有用:

#!/usr/bin/env ruby

class C

  def initialize
    create_method
  end


  def create_method
    private_create_method
  end


  private
  def private_create_method
    class << self
      define_method(:foo) { puts "I am a public method." }
    end
  end
end

C.new.foo # outputs: I am a public method.

答案 2 :(得分:0)

使用:

MyClass.instance_eval { public :public_method }

或运行:

public :public_method

来自MyClass类。

答案 3 :(得分:0)

如果用

替换private_create_method
def private_create_method
  self.class.send(:define_method, :foo) { puts "I am a public method." }
end

然后

C.new.foo
I am a public method