Ruby Enumerator - зачем заканчивать с исключением? - PullRequest
7 голосов
/ 09 июля 2010

Итерация блока в Ruby достаточно проста - он завершается чисто и переходит к остальной части кода.

Итерации с помощью Enumerator, с другой стороны, немного запутывают. Если вы звоните: каждый без блока, вместо этого возвращается Enumerator. Затем можно вызвать: next для перечислителя, чтобы получить каждое следующее итеративное значение.

И затем странная часть - когда итерация завершена, вместо перечислителя, возвращающего nil, выдается исключение: «итерация достигнута в конце» В результате он даже не возвращает значение.

Например:

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

Является ли причина этого просто для того, чтобы перечислитель мог вернуть значения nil? Ответ приходит ко мне только тогда, когда я отправляю это сообщение (поэтому я собираюсь опубликовать его до сих пор), но, похоже, это так.

Если это так, это типичный способ решения таких проблем? Кажется странным использовать Исключение для обработки кода, который, по сути, работает так, как ожидалось.

Ответы [ 2 ]

7 голосов
/ 09 июля 2010

Вы правы в том, что причина в том, что перечислитель может вернуть 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), поэтому этот базовый механизм не так часто раскрывается.

4 голосов
/ 09 июля 2010

Да, ноль все еще результат, который отличается от отсутствия значения для возврата.По сути, это то же самое, что пытаться получить доступ к переменной или месту в памяти, которого там нет.Вот почему вы хотите исключение, а не возвращать ноль.Похоже, вы поняли это: -)

...