Lexical scope in Ruby

From the “Progamming Languages” Coursera course
(https://class.coursera.org/proglang-003), this is a characteristic of a
lexically scoped language:
val x = 1
fun f y = x + y
val x = 2
val y = 3
val z = f (x+y)
z should result in 6

However, when I run it in Ruby 2.1.1 irb, it produces 7. What am I
missing?

2.1.1 :001 > x = 1
=> 1
2.1.1 :002 > b = Proc.new {|y| x + y}
=> #Proc:[email protected]:2(irb)
2.1.1 :003 > b.call(3)
=> 4
2.1.1 :004 > x = 2
=> 2
2.1.1 :005 > y = 3
=> 3
2.1.1 :006 > z = b.call(x+y)
=> 7

2.1.1 :001 > x = 1
=> 1
2.1.1 :002 > b = Proc.new {|y| x + y}
=> #Proc:[email protected]:2(irb)
2.1.1 :003 > b.call(3)
=> 4
2.1.1 :004 > x = 2 # you override x, now is 2
=> 2
2.1.1 :005 > y = 3 # this doesn’t matter, has no point
=> 3
2.1.1 :006 > z = b.call(x+y) # you pass 5 here, 2 + 5 = 7
=> 7

What happens is that if you use the same name for a local variable, as
an argument name inside #Proc b, inside the #Proc the argument take
relevance over the local variable outside its scope, “inner” scopes put
relevance to things created inside it first, for example: #Proc first
looks if there’s an argument name called x, if not looks outside the
scope, and so on. As y was defined inside the scope of the proc that’s,
no more searching.

Block arguments “shadow” variables defined in an outer scope and are
local to that block (at least since Ruby 1.9). Other refer to enclosing
scope, so x inside b = Proc.new {|y| x + y} can be changed outside
the block.

You are probably looking for a (lexical) closure, which “saves”
variables at the point of definition of the closure.
You may “catch” an environment generally by a method/proc/lambda
returning your proc with x applied or use “currying” ie. partial proc
application:

x = 1

now we define a closure using a method

def get_closure(x_cl); proc {|y| x_cl + y}; end

and assign returned proc to b1

b1 = get_closure(x)

another way with currying

b2 = proc {|x_cl, y| x_cl + y}.curry[x]
p b1[3] # 4
p b2[3] # 4
x = 2; y = 3
p b1[x+y] # 6
p b2[x+y] # 6