Ruby动态创建方法和变量

Jak*_*Zak 2 ruby variables methods dynamic instance

如何用更合理的东西替换add_entry方法?

class MyStorageClass

    def add_entry key, value
        eval "(@#{key} ||= []) << value; def #{key}; @#{key}; end"
    end

end
Run Code Online (Sandbox Code Playgroud)

那么我可以按如下方式检索值:

def get_entry key
    begin
        self.send key.to_sym
    rescue NoMethodError
        nil
    end
end
Run Code Online (Sandbox Code Playgroud)

And*_*rtz 6

而不是每个键的实例变量,这需要一些不必要的庞大的代码,为什么不只是像下面的单个哈希.此外,define_methoddefine_singleton_method可以成为你的朋友,以避免坏人坏事eval秒.

class MyStorageClass
  def initialize
    @data = {}
  end

  def add_entry(key, value)
    (@data[key] ||= []) << value
    define_singleton_method(key){ @data[key] }
  end

  def get_entry(key)
    @data.key?(key) or raise NoMethodError
    @data[key]
  end
end
Run Code Online (Sandbox Code Playgroud)

您可能想要检查您是否首先覆盖预定义的方法(!@data.key?(key) && self.respond_to?(key)在方法的顶部add_entry会这样做),但那是另一个对话.可能是坏的,如果有人试图添加键调inspect,class或哦,get_entry为例子!