Los iteradores no son un concepto original de Ruby. Son comunes en otros lenguajes orientados a objetos. También se utilizan en Lisp aunque no se les conoce como iteradores. Sin embargo este concepto de iterador es muy poco familiar para muchas personas por lo que se explorará con detalle.
Como ya se sabe, el verbo iterar significa hacer la misma cosa muchas veces, por lo tanto un iterador es algo que hace la misma cosa muchas veces.
Al escribir código se necesitan bucles en diferentes situaciones. En C, se codifican utilizando for o while. Por ejemplo:
La sintaxis del for(...) de C nos dota de una abstracción que nos ayuda en la creación de un bucle pero, la comprobación de si *str es la cadena nula requiere que el programador conozca los detalles de la estructura interna de una cadena. Esto hace que C se parezca a un lenguaje de bajo nivel. Los lenguajes de alto nivel se caracterizan por un soporte más flexible a la iteración. Consideremos el siguiente guión de la shell sh: Se procesarían todos los ficheros fuentes en C y sus cabeceras del directorio actual, el comando de la shell se encargaría de los detalles de coger y sustituir los nombres de los ficheros uno por uno. Pensamos que este es un método de trabajo a nivel superior que C, ¿Verdad?Pero hay más cosas a tener en cuenta: aunque está bien que un lenguaje tenga iteradores para todos los tipos de datos definidos en él, es decepcionante tener que volver a escribir bucles de bajo nivel para los tipos de datos propios. En la POO, los usuarios definen sus propios tipos de datos a partir de otros, por lo tanto, esto puede ser un problema serio.
Luego, todos los lenguajes OO incluyen ciertas facilidades de iteración. Algunos lenguajes proporcionan clases especiales con este propósito; Ruby nos permite definir directamente iteradores.
El tipo strings de Ruby tiene algunos iteradores útiles:
each_byte es un iterador sobre los caracteres de una cadena. Cada carácter se sustituye en la variable local c. Esto se puede traducir en algo más parecido a C ...ruby> s="abc";i = 0 0 ruby> while i < s.length ruby| printf "{%c}",s[i]; i+=1 ruby| end; print "\n" {a}{b}{c} nil |
each_line es otro iterador de String.
Las tareas que más esfuerzo llevan en C (encontrar los delimitadores de línea, generar subcadenas, etc.) se evitan fácilmente utilizando iteradores.La sentencia for que aparece en capítulos previos itera como lo hace el iterador each. El iterador each de String funciona de igual forma que each_line, reescribamos ahora el ejemplo anterior con un for:
Se puede utilizar la sentencia de control retry junto con un bucle de iteración y se repetirá la iteración en curso desde el principio.ruby> c = 0 0 ruby> for i in 0..4 ruby| print i ruby| if i == 2 and c == 0 ruby| c = 1 ruby| print "\n" ruby| retry ruby| end ruby| end; print "\n" 012 01234 nil |