2016-05-23 52 views
0

我有以下方法:紅寶石:在循環跳過元素,如果將引發異常

def fetch_something 
    @fetch_something ||= array_of_names.inject({}) do |results, name| 
    begin 
     results[name] = fetch_value!(name) 
    rescue NoMethodError, RuntimeError 
     next 
    end 

    results 
    end 
end 

其目的:它獲取對於給定name的值可以提高一個錯誤,在這種情況下,它會忽略name並嘗試下一個。

雖然這工作得很好,我得到來自Rubocop一個錯誤,指出:

棉絨/ NextWithoutAccumulator:下次使用與 蓄能器參數一個減少。

谷歌搜索的錯誤使我http://www.rubydoc.info/gems/rubocop/0.36.0/RuboCop/Cop/Lint/NextWithoutAccumulator地方說,不省略蓄能器,這將導致一個方法看起來像這樣:

def fetch_something 
    @fetch_something ||= array_of_names.inject({}) do |results, name| 
    begin 
     results[name] = fetch_value!(name) 
    rescue NoMethodError, RuntimeError 
     next(name) 
    end 

    results 
    end 
end 

的問題是,這一變化打破了其他處理方法。任何想法如何解決?

更新:實證例子:
array_of_names = ['name1','name2','name3'] 

def fetch_value!(name) 
    # some code that raises an error if the name doesn't correspond to anything 
end 

fetch_something 

# => {'name1' => {key1: 'value1', ...}, 'name3' => {key3: 'value3', ...}} 
# 'name2' is missing since it wasn't found durcing the lookup 
+0

那麼試試'next(results)'而不是? – user12341234

+0

@ user12341234這也打破了它。 – Severin

+0

也許你可以顯示樣本輸入/輸出來衡量預期的行爲? – user12341234

回答

2

使用您的示例代碼,似乎next(results)不解決這個問題對我來說。我用的是拋出一個KeyError代替NoMethodErrorRuntimeError一些測試代碼,但這個想法仍然是相同的:

@array_of_names = ['name1','name2','name3'] 

def fetch_value!(name) 
    {'name1' => 'n1', 'name3' => 'n3'}.fetch(name) 
end 

def fetch_something 
    @fetch_something ||= @array_of_names.inject({}) do |results, name| 
    begin 
     results[name] = fetch_value!(name) 
    rescue NoMethodError, RuntimeError, KeyError 
     next(results) 
    end 

    results 
    end 
end 

p fetch_something 

此代碼輸出:

{"name1"=>"n1", "name3"=>"n3"} 

而且,我同意@Алексей Кузнецовeach_with_object可能是每當你的塊代碼改變你正在嘗試構建的數據結構時要走的路。所以我的fetch_something優選實現可能更喜歡這樣的:

def fetch_something 
    @fetch_something ||= @array_of_names.each_with_object({}) do |name, results| 
    begin 
     results[name] = fetch_value!(name) 
    rescue NoMethodError, RuntimeError, KeyError 
     # error handling 
    end 
    end 
end 

注意,在我的例子begin/end分配給results[name]對比@АлексейКузнецов的例子將分配nil到每次發生異常時都會散列。

+0

謝謝您的回覆! – Severin

0

只需使用each_with_object

def fetch_something 
    @fetch_something ||= array_of_names.each_with_object({}) do |name, results| 
    results[name] ||= begin 
         fetch_value!(name) 
         rescue NoMethodError, RuntimeError 
         end 
    end 
end 
+0

這也打破了它的原始功能。 – Severin