I am learning ruby at the moment. I am trying to understand the way closures work, and how they are different from functions. I am fully aware that closures should be implemented via proc or lambda.
I am trying to get an in depth understanding of ruby. As such I checking all kinds of unorthodox code. I am trying to understand why line 3 works while line 5 is an error.
x=123
def b(x)
p x
def a(u)
p x # why is this an error?!?!?
end
a 4
end
b 1
This is purely a learning exercise, I am doing this to understand what is going on beneath the hood.
It's something called the "scope gate". Basically, when you start a definition of a method/class/module, a new scope is created and all local variables from other scopes can't be accessed. This doesn't apply to instance/global variables, you'll keep access to those.
Since a lambda isn't a method, it doesn't create new scope and reuses existing one instead.
Also,
why line 3 works
x = 123
def b(x)
p x # this "x" is "x the parameter", not "x the local variable from outer scope"
# that's why it works. If you tried to access the local var, it wouldn't work.
def a(u)
p x # like here, see? Doesn't work.
end
a 4
end
b 1
The first thing to understand is that def
does not make a "function" (what does that even mean in Ruby?) -- def
defines a method on some object or class. Even when it appears to be not inside any object, it still defines a method on the "main" object. So when you do def a
, it is not "local" to the method b
; it is a method a
just like if you defined it at the top level, except that it doesn't get defined until b
runs. It can be called as the method a
from other places. You have nested method definitions.
Because it was meant to define methods, which most of the time is defined at the top level of a class or module, def
was never made to capture outside variables.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With