Un bloque es una porción de código encerrada entre paréntesis {}
o entre do…end
. Por lo tanto, un bloque es una forma de agrupar instrucciones, y solo puede aparecer después de usar un método: el bloque empieza en la misma línea que usa el método. El código dentro del bloque no es ejectuado en el instante que el intérprete de Ruby lo encuentra: Ruby se recordará del bloque (variables locales, …) y después entra en el método, ejecutando el bloque cuando es preciso.
Supongamos que existen dos métodos llamados greet1 y greet2:
#greet1, no necesita argumentos
greet1 {puts 'Hola'}
#greet2, necesita un argumento
greet2 ("argumento_cualquiera") {puts 'Hola'}
Lo usual es usar las {}
para bloques de una línea y el do…end
para más de una línea.
Un método puede usar el bloque mediante la palabra yield:
def metodo
puts 'Comienzo del metodo'
yield
yield
puts 'Final del metodo'
end
metodo{puts 'Dentro del bloque'}
La salida es:
'Comienzo del metodo'
'Dentro del bloque' # primer yield
'Dentro del bloque' # segundo yield
'Final del metodo'
Lo que sucede es que en el momento que el intérprete llega al yield, se ejecuta el código dentro del bloque, y luego se retorna al método.
En los bloques se pueden usar argumentos especificándolos dentro de dos barras verticales | |
. Y si se usan, en el yield no podemos olvidar darles valor:
def metodo
yield('hola', 99)
end
metodo{|str,num| puts str + ' ' + num.to_s} #hola 99
Un bloque de código devuelve un valor: el valor de la última expresión evaluada. Y este valor devuelto por yield, puede usarse dentro del método que invoca el bloque.
Los bloques no son objetos, pero pueden convertirse en ellos gracias a la clase Proc
. Estos objetos son bloques que se han unido a un conjuto de variables locales. Esto se hace gracias al método lambda del módulo Kernel
.
prc = lambda{ "hola" }
Un bloque creado con lambda actúa como un método: si no especificas el número correcto de argumentos, no puedes llamar al bloque. La clase Proc tiene un método para llamar al bloque: el método call
.
prc = lambda {puts 'Hola'}
prc.call #llamamos al bloque
#otro ejemplo
toast = lambda do
puts 'Gracias'
end
toast.call
La salida es:
Hola
Gracias
Para usar argumentos con lambda:
aBlock = lambda { |x| puts x }
aBlock.call 'Hola Mundo!'
La salida es:
Hola Mundo!
Los procs son muy útiles por que:
#uso de procs como argumentos
def metod1 proc1
puts 'Principio del metodo'
proc1.call
puts 'Final del metodo'
end
hola = lambda do
puts 'Hola'
end
metod1 hola
La salida es:
Principio del metodo
Hola
Final del metodo