Subsecciones


Clausuras y Bindings

La clase Proc define un método denominado binding. Cuando se llama este método en un proc o en una lambda retorna un objeto Binding que representa las ligaduras en efecto para esa clausura.

Los bindings conllevan mas que variables: guardan toda la información necesaria para poder ejecutar el método incluyendo el valor de self y - si existe - el bloque que será ejecutado con yield

# Return a lambda that retains or "closes over" the argument n
def multiplier(n) 
  lambda {|data| data.collect{|x| x*n } }
end
doubler = multiplier(2)     # Get a lambda that knows how to double
puts doubler.call([1,2,3])  # Prints 2,4,6

El Módulo Kernel proporciona la función global eval que admite como segundo argumento un objeto Binding que provee el contexto para evaluar la cadena de código Ruby:

eval("n=3", doubler.binding) # Or doubler.binding.eval("n=3") in Ruby 1.9
puts doubler.call([1,2,3])   # Now this prints 3,6,9!
Como atajo, el método eval nos permite pasar directamente un objeto Proc en vez de pasar el Binding del objeto Proc:
eval("n=3", doubler)

El método binding de Kernel retorna un objeto Binding que representa los bindings en efecto en el punto de la llamada.

[~/Chapter6MethodsProcsLambdasAndClosures]$ cat binding.rb 
def tutu(p)
  x = 4
  x = 2*p
  return [p, binding]
end
p, b = tutu(8)
p eval("p", b) #  8  
p eval("x", b) # 16

Véase

  1. An Introduction to Procs, Lambdas and Closures in Ruby (CooperPress) (YouTube)

Casiano Rodriguez León 2015-01-07