viernes, 6 de febrero de 2009

Usa yield, por que si no lo usas se oxida

Sin duda, yield es un elemento muy poderoso de estos lenguajes de programación "modernos", en definitiva, lo que yield hace es invocar el bloque de código que se le paso por parámetro a un método especifico. Un ejemplo




def foo(x)
if x < 3
yield
end
end

foo(2) { print "hola mundo" }




Con la sola definición de yield no es sencillo darse cuenta rápidamente de como podría aplicarse, pero para que se den una idea, todos los métodos del array que reciben bloques estan implementados usando yield, estos son (entre otros), each, inject, select, find, etc..., también métodos como synchronize del mutex usan yield con propósitos de RAII y con un sin fin de aplicaciones. Aca otro ejemplo:



# compone cualquier funcion dos veces, toma como inicio el parámetro
def compdouble(x)
yield(yield(x))
end

# devuelve x*x*x*x = 81 (composicion doble de x*x)
print compdouble(3){ |x| x*x }, "\n"



también puede servir para pasar expresiones como parámetros, que solo seran evaluadas si se necesitan, la siguiente idea se aplico en el logger de rsif



# invocamos logger.info con parametro normal, entonces el
# interprete siempre evalúa la expresión
# para pasarle el parámetro a logger.info,
#sin importar si logger info vaya a loguear o no
# aveces evaluar determinadas expresiones conlleva
# a invocar metodos, accesar a bases de datos,
# hacer calculos, etc..

logger.info Locale.hello_world

# Es mejor si en lugar de pasarle el paremetro
# normalmente, se lo pasemos en un bloque
# entonces el bloque solo sera invocado
# si el parametro necesita ser evaluado, es decir
# cuando el metodo decida que va a loguearlo, definitivamente

logger.info { Locale.hello_world } # las llaves hacen que se pase el bloque de código

# pseudo-codigo resumido de logger.info:

def logger.info( x = nil )
if loguear
if block_given?
print yield,"\n"
else
print x,"\n"
end
end
end



Otro ejemplo es la implementación de visitor pattern usando ruby, con yield es muy cómoda de implementar y también de usar (el link que les pase hace la comparativa entre la implementación de lo mismo en varios lenguajes)

Espero que les haya sido de utilidad, hasta el próximo post

No hay comentarios: