2011-06-24 23 views
1

我從來沒有需要在Ruby中這樣做,但我的老闆,作爲一個C程序員,給我一個問題,我真的不能提供一個優雅的解決方案Ruby,基本上不用C語言(使用兩個「break」語句來跟蹤變量)。這樣做的功能是什麼? (打破兩個嵌套的#each塊)

我們有這樣的(解析XML)的情況:

(1..1000).each do |page| 
    fetch_page(page).results.each do |results| 
    do_something_with_results! 
    break if results[:some_value] > another_value # this needs to exit BOTH blocks 
    end 
end 

我能做到這一點的唯一方法是,我不會形容爲非常紅寶石般的一種方式,更是C方式的思考。例如:

(1..1000).each do |page| 
    should_break = false 
    fetch_page(page).results.each do |results| 
    do_something_with_results! 
    if results[:some_value] > another_value 
     should_break = true 
     break 
    end 
    end 
    break if should_break 
end 

對我來說,這感覺完全錯誤和un-Ruby樣,但什麼是功能方法?

+0

可能的重複:http://stackoverflow.com/questions/1352120/how-to-break-outer-cycle-in-ruby –

+3

雖然'throw'&'catch'是專爲這種情況設計的Ruby關鍵字,檢查你是否可以用自己的方法包裝這些代碼,並使用'return'分解。 _通常它會提供更多可讀/可測試的代碼。 – captainpete

+0

@Jordan:可能的重複僅討論解決問題的過程式編程風格。 –

回答

4
catch (:break) do 
    (1..1000).each do |page| 
    fetch_page(page).results.each do |results| 
     do_something_with_results! 
     throw :break if results[:some_value] > another_value # this needs to exit BOTH blocks 
    end 
    end 
end 

編輯:以上 @ CaptainPete的評論是即期。如果你能把它變成一個功能,它有很大的副作用(單元測試是主要的)。

+0

哇,我記得讀過這本書的時候,我讀了一本紅寶石書的前面,但從來沒有真正見過它用過:)謝謝。 – d11wtq

-1

這取決於你的情況。

如果數據集不是太大,你可以做

results = (1..1000).map{|page_number| fetch_page(page_number).results}.flatten(1) 
results.each do 
    do_something_with_results! 
    break if results[:some_value] > another_value # this needs to exit BOTH blocks 
end 

,否則你就必須做一些事情,使之更加懶惰,如

def each_result(page_numbers) 
    page_numbers.each do |page_number| 
    fetch_page(page_number).results.each do |result| 
     yield result 
    end 
    end 
end 

和我確定有很多其他的方法可以讓你懶惰。