let binding

 def let(*values); yield *values; end
 def let(*values, &block)
   block.call(*values) if block_given?
 end


example:

 let (metainfo['info']) { |info|
   info['name'] = name
   info['pieces] = pieces.join
   info['piece length'] = 2**18
 }

If write this with lambda or proc.

 lambda {|info|
  # : same
 }.call(metainfo['info'])

Since ruby's function can take a block argument, and have closure,
It works like let binding. but its in limited context,
there was an exception which i dont expect

 def let(*values); yield *values; end

 n = num = 0
 s = str = "Hello"

 p n, num
 p s, str

 let (num) { |n| p n; n = n } # left n is global, right n is local...
 let (str) { |s| p s; s = "world" }

 p n, num
 p s, str

In the block, p n shows value of num,
but n = 1000 changes global variable 'n'. its not local variable !?
seem this is known problem at ruby.

I'm thinking how to define 'with' statement.