2010-07-09 26 views
6

在Ruby中對塊進行迭代非常簡單 - 它乾淨地完成並繼續執行其餘的代碼。Ruby Enumerator - 爲什麼以異常結束?

另一方面,使用枚舉器進行迭代更容易混淆。如果你調用:每一個都沒有塊,​​則返回一個枚舉器。 :接下來可以在枚舉器上調用以獲取每個下一個迭代值。

然後當迭代完成,而不是枚舉返回無奇兼職,它拋出一個異常:「在迭代結束時達到」。結果是它甚至不返回一個值。

例如:

test = [ 'test_value' ] 
enumerator = test.each 
enumerator.next 
>> "test_value" 
enumerator.next 
>> StopIteration: iteration reached at end 

簡直讓零值可以通過枚舉器返回的原因呢?答案只發生在我發佈這個(所以我會發布它仍然),但似乎一定是這種情況。

如果是這樣,這是處理這些問題的典型方法嗎?使用異常來處理基本上按預期執行的代碼似乎很奇怪。

回答

6

你是正確的,其原因在於,這樣可以nil由枚舉有效的值返回。要回答你是否這是典型的問題,Python使用一個異常(也稱爲StopIteration)以相同的方式處理它。

>>> my_list = [1,2,3] 
>>> i = iter(my_list) 
>>> i.next() 
1 
>>> i.next() 
2 
>>> i.next() 
3 
>>> i.next() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
StopIteration 

當然,大部分時間next不直接調用(each或被用來代替for循環),從而這個潛在的機制不被暴露,往往。

+1

OCaml的走得更遠 - 紅寶石的'散列的更多或更少的當量[鍵]'('List.assoc鍵hash')引發一個例外('Not_found')如果密鑰不表示。這實際上是非常合乎邏輯的 - 當你調用':next'時,你期望的「正常」是獲得下一個值。 *不*獲得下一個值顯然是一種特殊情況。 – Amadan 2010-07-09 15:47:20

+1

@Amadan:如果找不到密鑰,'hash.fetch(key)'會引發一個'KeyError'。 – 2010-07-09 17:17:02

+0

有趣的說法阿馬丹 - 我買了它。 – Asher 2010-07-10 02:41:47

3

是的,零仍然是一個結果,這是不同於沒有價值返回。這與嘗試訪問不存在的內存中的變量或位置基本相同。這就是爲什麼你想要一個異常,而不是返回零。聽起來像是你想通了這一點:-)