2013-05-03 115 views
0

假設我有一個類定義了我的日子集合以及它們的古怪程度。它是更好地初始化我@scores在初始化函數變量,像這樣:初始化中計算實例變量的最簡潔方法是什麼?

class WackyDayScorer 
    attr_reader :scores 
    def initialize(start = Time.now, max = 90.days) 
    @start = start 
    @limit = start - max 
    @scores = get_scores 
    end 

private 
    def get_scores 
    result = [] 
    t = @start.clone 
    until t < max 
     result << score_wackiness(t) 
     t -= 1.day 
    end 
    result 
    end 
end 

或初始化它在get_scores方法,像這樣:

class WackyDayScorer 
    attr_reader :scores 

    def initialize(start = Time.now, max = 90.days) 
    @start = start 
    @limit = start - max 
    get_scores 
    end 

private 
    def get_scores 
    @scores = [] 
    t = @start.clone 
    until t < max 
     @scores << score_wackiness(t) 
     t -= 1.day 
    end 
    end 
end 

回答

0

第一種是完全錯誤的。你是說

@scores = get_scores 

get_scores沒有返回一個有用的值,所以這是堅果。相反,get_scores設置@scores直接和內部作爲副作用。

第二個至少是連貫的。

就個人而言,雖然,我不會做的事情要麼。我會說,你說什麼第一次:

@scores = get_scores 

但是我執行get_scores不願觸及的伊娃。如果你想處理在初始化的東西,創建來處理計算一個私有方法,然後設置在#initialize實例變量

def get_scores 
    scores = [] 
    # do stuff to scores 
    return scores # or simply, scores 
    end 
+0

我不會_return_任何值,因爲慣用Ruby使用方法調用的隱式返回。 – Chris 2013-05-03 23:55:29

+0

對,但是返回的局部變量值仍然需要處於最後位置以隱式返回。 – matt 2013-05-03 23:58:18

+0

修復了您在第一個示例thx中指出的錯誤。看起來像你說的第一個解決方案是你會選擇的解決方案。 – muirbot 2013-05-04 00:01:22

0

:這將返回的實際值。如果你想在不刪除實例變量的情況下在類的其他地方重新使用該計算,我不會在方法中設置它。

class WackyDayScorer 
    attr_accessor :scores 

    def initialize(start = DateTime.now, max = 90.days) 
    @start = start 
    @limit = start - max 
    @scores = calculate_scores 
    end 

private 

    def calculate_scores 
    (@[email protected]).to_a.map { |date_time| score_wackiness(date_time) } 
    end 
end 

在#calculate_scores,我們正在創建的限定日期和開始之間的範圍(倒數,當你在做),每個結果發送到#score_wackiness方法。

+0

我決定不這樣做,因爲這個值總是會在每次有人時計算出來使用這個類。爲什麼推遲不可避免的? – muirbot 2013-05-04 00:04:12

+0

更新了我認爲你想要的答案 – Chris 2013-05-04 00:16:52

0

我建議你明確地定義爲得分,吸氣,memoizing計算並跳過所有的儀式:

class WackyDayScorer 
    def initialize(start = Time.now, max = 90.days) 
    @start = start 
    @limit = start - max 
    end 

    def scores 
    @scores ||= begin 
     result = [] 
     t = @start.clone 
     until t < max 
     result << score_wackiness(t) 
     t -= 1.day 
     end 
     result 
    end 
    end 
end 

這基本上是你在做什麼,無論如何,但它更直接。

+0

我喜歡這個。但我不認爲我會稱它爲「memoization」;它只是懶惰的初始化(通過getter)。 – matt 2013-05-04 01:58:29

+0

@matt使用'|| ='並將它分配給一個實例變量*是* memoization。你可以[閱讀更多關於什麼memoization在這裏](http://www.reference.com/browse/wiki/Memoization)。 – Cade 2013-05-04 03:48:46

+0

我不同意,我不認爲你正在閱讀文章。記憶是將f(x)的值存儲在某個昂貴函數f下的每個不同x *的值的技術,因此如果對同一個參數值再次進行相同的調用,則不必重新計算。例如https://github.com/djberg96/memoize – matt 2013-05-04 04:18:30

相關問題