在ruby中动态定义记忆getter

在ruby中动态定义记忆getter,ruby,metaprogramming,Ruby,Metaprogramming,使用Ruby,我想在相应的getter中动态创建类级实例变量。对于其中两个,我使用attr_reader。但对于需要初始化为空数组的数组,我执行以下操作: class MatchMake class << self attr_reader :local_data, :remote_data ["type1", "type2"].each do |elem| define_method "#{elem}_matches".to_sym do

使用Ruby,我想在相应的getter中动态创建类级实例变量。对于其中两个,我使用attr_reader。但对于需要初始化为空数组的数组,我执行以下操作:

class MatchMake
  class << self
    attr_reader :local_data, :remote_data
    ["type1", "type2"].each do |elem|
      define_method "#{elem}_matches".to_sym do
        instance_variable_set("@#{elem}_matches", [])
      end
    end
  end
  ...
end
def type1_matches
  @type1_matches ||= []
end

首先,您定义的是
type1\u匹配
,而不是
type1
。其次,
define_方法
接受字符串,
#to_sym
是多余的。最后,但并非最不重要的一点是,您定义getter实际上是setter。因此,要根据需要定义
type1

define_method "#{elem}=", value do
  instance_variable_set("@#{elem}", value)
end
现在,对于getter,延迟实例化为空数组:

define_method "#{elem}" do
  instance_variable_set("@#{elem}", []) \
      unless instance_variable_defined?("@#{elem}")
  instance_variable_get("@#{elem}")
end

以下是我为此类用例编写的示例模式:

下面是它的代码:

# memoize db/cache results in instance variable dynamically
def memoize_results(key)
  return instance_variable_get(key) if instance_variable_defined?(key)
  instance_variable_set key, yield  
end

# usage
MY_CONSTANT = [:active, :inactive]
MY_CONSTANT.each { |key|
  define_method("#{key}_users") do
    memoize_results("@#{key}_users") do
      User.send(key).all # assumes that user responds to active, inactive(via scope/filter etc..)
    end
  end
}

我的错误是,我的代码应该是def type1_MATCHS,我将编辑问题以反映上述内容。欢迎链接到解决方案,但请确保您的答案在没有它的情况下是有用的:这样您的其他用户就会知道它是什么以及为什么存在,然后引用你链接到的页面最相关的部分,以防目标页面不可用。
# memoize db/cache results in instance variable dynamically
def memoize_results(key)
  return instance_variable_get(key) if instance_variable_defined?(key)
  instance_variable_set key, yield  
end

# usage
MY_CONSTANT = [:active, :inactive]
MY_CONSTANT.each { |key|
  define_method("#{key}_users") do
    memoize_results("@#{key}_users") do
      User.send(key).all # assumes that user responds to active, inactive(via scope/filter etc..)
    end
  end
}