2015-09-02 24 views
-1

在一個類的方法,我有以下行賦值語句:減少長度和/或幹出來的發生基於存在

self.some_hash[:some_key] = change_it(self.some_hash[:some_key]) if self.some_hash[:some_key].present? 

它的工作原理,但它是一個漫長的說法,主要是因爲我是在重複self.some_hash[:some_key]在賦值語句中三次。

是否有一些紅寶石語法糖爲此我可以縮短這行代碼?也許通過做一些句法糖減少三次重複self.some_hash[:some_key],或者可能是另一種技巧?

回答

2

這條特別的路線不可能很快被重寫(至少我沒有看到任何合理的方法),主要是因爲整個設計並不是很有意思。

  1. 使用就地改變而不是重新分配。 a = change_it(a)是壞的,a.change_it是好的(只要有可能,事實證明它幾乎總是可能的。)
  2. a.present?在大多數情況下是多餘的檢查。你真的需要它嗎?會不會普通舊好紅寶石if a足夠?

隨着重構上面的考慮,上述codepiece將成爲:

用簡單的檢查爲nil or false

self.some_hash[:some_key] &&= change_it self.some_hash[:some_key] 

有兩個變化:

self.some_hash[:some_key].tap { |v| v.change_it if v } 

我理解這不是你的問題的確切答案,但我希望這可能會有所幫助。

UPD正如@WandMaker所指出的那樣,self在這裏看起來可疑多餘。

+1

另外,想知道是否需要'self'? –

+0

@WandMaker好點。 – mudasobwa

+0

如何在'tap'中設置'change_it'作爲'v'的方法 - 不確定代碼的工作原理 - 我只是想了解 –

1

有一個簡單的替代

hash[:key] &&= change_it(hash[:key]) 

,但它僅適用於nil檢查,也不會重新設定值,如果它是假的,這可能是也可能不是你想要的。雖然.present?不僅檢查零,而且當給定一個字符串或數組時,如果非空。

或者,爲什麼不只是定義一個方法?

E.g.

def change_if_present(hash, key) 
    hash[key] = change_it(hash[key]) if hash[key].present? 
end 

,或者如果你要爲一串鑰匙做同樣的,你可以只寫

[:key_a, :key_b, ...].each do |key| 
    hash[key] = change_it(hash[:key]) if hash[:key].present? 
end 

然後你甚至可以包裝在一個方法

def change_values_if_key_present(hash, keys) 
    keys.each do |key| 
    hash[key] = change_it(hash[key]) if hash[key].present? 
    end 
end 

中當然這假設所有鍵的改變是相同的。