miércoles, 21 de noviembre de 2007

Tema 6: Bloques e iteradores

En programacion, recorrer un array, es un proceso en el que hay que tener en cuenta varias cosas:
-Un bucle para recorrer el array
-Saber la longitud del array
-Recuperar cada elemento para saber si es el que buscamos
Ejemplo:

a = [1, 2, 3]
for i in 0..a.length-1
a[i] += 1
end

En ruby existe una manera más facil de hacer esto, utilizando los iteradores.
Un iterador es un método capaz de invocar a un bloque de código de forma repetida.
El metodo "each" es un ejemplo de iterador:

a = [1, 2, 3]
a.each{|elemento| elemento += 1}

Otros ejemplos de iteradores: find, collect,select...

Esto nos libera de código y lo hace más sencillo, ya que el propio iterador implementa el blucle, y se le puede pasar cualquier operación que queramos hacer con el array.

¿Que son los bloques?

En Ruby es un modo de agrupar sentencias, dando una mayor flexibilidad pero con algunas particularidades:

- Un bloque puede aparecer solamente en el código adyacente a la
invocación de un método

-No se ejecuta cuando se encuentra

-Dentro del método se le hace una llamada "yield" y se ejecuta.

Vamos a verlo con un ejemplo sencillo:

def Hola
yield
yield
yield
end

"tenemos un metodo, que mediante el yield llama al bloque, invocando el contenido del bloque"

Hola{puts "Hello"}

"Bloque simple que muestra Hello"

El resultado por pantalla sería:

Hello
Hello
Hello

Los bloques pueden recibir parámetros, y la última expresion evaluada en el bloque se entrega al método como el valor del yield.

Ejemplo:

class Array
def find
for i in 0...size
value = self[i]
return value if yield(value)
end
return nil
end
end
[1, 3, 5, 7, 9].find {|v| v*v > 30 } >> 7

Los bloques pueden definirse mediante llaves:

[1,2,3,4,5,6].impares{|e| e**2}

o mediante los elementos do .. end:

[1, 3, 5, 7, 9].find do |v|
v*v > 30
end

Por último los bloques pueden usarse para definir una porción de código que
debe ejecutarse bajo algún tipo de control transaccional, por ejemplo
operaciones con ficheros.

Ejemplo:

class File
def File.openAndProcess(*args)
f = File.open(*args)
yield f
f.close()
end
end
File.openAndProcess("testfile","r") do |aFile|
print while aFile.gets
end

No hay comentarios: