2015-07-03 21 views
1

使用Ruby,我想在相應的getter中動態創建類級別的實例變量。對於其中的兩個,我使用attr_reader。但是,對於那些需要被初始化爲空數組,我做了以下內容:在ruby中動態定義memoized getter

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 

首先,我想知道我是否糾正我的理解。其次,我想知道如果有memoize的變量的方式,如下面的:

所有的
def type1_matches 
    @type1_matches ||= [] 
end 

回答

2

首先,定義type1_matches,不type1。其次,define_method接受字符串,#to_sym是多餘的。最後但並非最不重要的一點是,你定義的getter實際上是一個setter。因此,定義type1,你想:現在

define_method "#{elem}=", value do 
    instance_variable_set("@#{elem}", value) 
end 

,吸氣劑,懶洋洋地實例化空數組:

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

我的錯,我的C ode應該讀取def type1_matches,會編輯上面反映的問題。 –

2

這裏是我寫了這樣的用例的樣本模式: 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 
} 
+1

歡迎您訪問解決方案的鏈接,但請確保您的答案在沒有它的情況下很有用:[在鏈接附近添加上下文](// meta.stackexchange.com/a/8259),以便您的同行用戶瞭解它是什麼以及爲什麼它在那裏,然後引用您鏈接的頁面中最相關的部分,以防目標頁面不可用。 [僅僅是一個鏈接的答案可能會被刪除。](// stackoverflow.com/help/deleted-answers) – FelixSFD

+0

我已經按照建議添加了代碼。 – Ritikesh