martes, 15 de enero de 2013

Ruby: Funciones en el valor de una Hash

Una Hash esta formada por pares clave-valor. en ocasiones, necesitaremos quealguno de esos valores sea una llamada a un método. Pongamos, por ejemplo, Time.now.

Si creamos la hash directamente con la llamada....

 hTime = {:a => Time.now}
 => {:a=>2013-01-15 10:45:58 +0100}

Cada vez que volvamos a acceder al elemento :a obtendremos lo mismo. No repite la llamada al método:

 
 hTime[:a]
 => 2013-01-15 10:45:58 +0100

La solución para  cuando queremos que el método se ejecute cada vez, es introducir una función lambda, con lo que podremos ejecutar el contenido del valor de la hash cuando queramos:

 hTime = {:a => lambda {Time.now}}
 => {:a=>#} 

Ahora, al hacer la llamada con la ejecución del procedimiento lambda:

 
hTime[:a].call
 => 2013-01-15 10:54:11 +0100

Si la repetimos, comprobamos que nuestra función se está llamando de nuevo:
 
hTime[:a].call
 => 2013-01-15 10:55:19 +0100

Un mini-ejemplo aplicado. Tenemos una hash. Uno de sus miembros es un array de numeros. El otro
miembro lo usaremos para saber si la suma del array es par.

 
hNumeros = {:nums => [1,2,3], :total_par => lambda{ hNumeros[:nums].sum.even?}}

hNumeros[:total_par].call
 => true 

Modificamos el array...
 
 hNumeros[:nums] << 7
 => [1, 2, 3, 7] 

hNumeros[:total_par].call
 => false 

Y de esta forma, realizamos la llamada a métodos y funciones desde el valor de una Hash