Enumerador Ruby - Por que terminar com exceção?
-
13-09-2020 - |
Pergunta
Iterar um bloco em Ruby é bastante simples - termina de forma limpa e prossegue para o resto do código.
Iterar com um Enumerador, por outro lado, é um pouco mais confuso.Se você chamar :each sem um bloco, um Enumerator será retornado.:next pode então ser chamado no Enumerador para obter cada próximo valor iterativo.
E então a parte estranha: quando a iteração é concluída, em vez do Enumerador retornar nulo, ele lança uma exceção:"iteração alcançada no final".O resultado é que ele nem retorna um valor.
Por exemplo:
test = [ 'test_value' ]
enumerator = test.each
enumerator.next
>> "test_value"
enumerator.next
>> StopIteration: iteration reached at end
A razão para isso é simplesmente para que valores nulos possam ser retornados pelo Enumerador?A resposta me ocorre apenas quando eu posto isso (então vou postar ainda), mas parece que deve ser o caso.
Se for assim, será esta uma forma típica de lidar com tais questões?Parece estranho usar uma exceção para lidar com código que funciona essencialmente conforme o esperado.
Solução
Você está certo ao dizer que a razão é que nil
pode ser retornado como um valor válido pelo Enumerador.Para responder à sua pergunta sobre se isso é típico, o Python trata isso da mesma maneira usando uma exceção também chamada 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
Claro, na maioria das vezes next
não é chamado diretamente (each
ou um for
loop sendo usado), então esse mecanismo subjacente não é exposto com tanta frequência.
Outras dicas
Sim, nil ainda é um resultado, o que é diferente de não ter um valor para retornar.É basicamente o mesmo que tentar acessar uma variável ou um local na memória que não existe.É por isso que você deseja uma exceção em vez de retornar nulo.Parece que você descobriu isso :-)