在 ruby 中动态定义 memoized getter
Define memoized getter dynamically in ruby
使用Ruby,我想在相应的getter中动态创建class级的实例变量。对于其中两个,我使用 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
根据我的理解,这段代码等同于:
class MatchMake
class << self
def local_data
@local_data
end
def remote_data
@remote_data
end
def type1_matches
@type1_matches = []
end
def type2_matches
@type2_matches = []
end
end
...
end
首先我想知道我的理解是否正确。其次,我想知道是否有一种方法可以记忆变量,如下所示:
def type1_matches
@type1_matches ||= []
end
首先,你定义的是type1_matches
,而不是type1
。其次,define_method
接受字符串,#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
下面是我为 use-cases 编写的示例模式:
https://gist.github.com/ritikesh/09384fec25c4b05cfdec8674ce3a9076
这是其中的代码:
# 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
}
使用Ruby,我想在相应的getter中动态创建class级的实例变量。对于其中两个,我使用 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
根据我的理解,这段代码等同于:
class MatchMake
class << self
def local_data
@local_data
end
def remote_data
@remote_data
end
def type1_matches
@type1_matches = []
end
def type2_matches
@type2_matches = []
end
end
...
end
首先我想知道我的理解是否正确。其次,我想知道是否有一种方法可以记忆变量,如下所示:
def type1_matches
@type1_matches ||= []
end
首先,你定义的是type1_matches
,而不是type1
。其次,define_method
接受字符串,#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
下面是我为 use-cases 编写的示例模式: https://gist.github.com/ritikesh/09384fec25c4b05cfdec8674ce3a9076
这是其中的代码:
# 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
}