Ruby local variable is undefined
In Ruby local variables only accessible in the scope that they are defined. Whenever you enter/leave a Class, a Module or a Method definiton your scope changes in Ruby.
For instance :
v1 = 1
class MyClass # SCOPE GATE: entering class
v2 = 2
local_variables # => ["v2"]
def my_method # SCOPE GATE: entering def
v3 = 3
local_variables # => ["v3"]
end # SCOPE GATE: leaving def
local_variables # => ["v2"]
end # SCOPE GATE: leaving class
These entering and leaving points are called Scope Gates. Since you enter through Scope Gate via method definition you cannot access your local_var
inside hello
method.
You can use Scope Flattening concept the pass your variable through these gates.
For instance instead of using def
for defining your method you can use Module#define_method
.
local_var = "Hello"
define_method :hello do
puts local_var
end
In the same way you can define your classes via Class#New
so that your scope does not change when you pass through class definition.
local_var = 'test'
MyClass = Class.new do
puts local_var #valid
end
instead of
class MyClass
puts local_var #invalid
end
In the same way you should use Module#New
if you want to pass your local variables through Module gates.
Example is taken from Metaprogramming Ruby
![Sergii Shevchyk](https://i.stack.imgur.com/j3vlZ.png?s=256&g=1)
Sergii Shevchyk
Updated on February 04, 2020Comments
-
Sergii Shevchyk over 4 years
I have the following Ruby code:
local_var = "Hello" def hello puts local_var end hello
I get the following error:
local_variables.rb:4:in 'hello': undefined local variable or method 'local_var' for main:Object (NameError) from local_variables.rb:7:in '<main>'
I always thought that local variables are not accessible from outside of the block, function, closure, etc.
But now I defined local variable in the file and try to get an access from the function INSIDE the same file.
What's wrong with my understanding?
-
Adam Tolley about 10 yearsIf I am in a car and I have change in my pocket, then there is change in the car. Plenty of other languages forward local variables to inner scopes, so there is no reason to treat Ruby's behavior as self evident.
-
Alexander Suraphel over 7 years@AdamTolley you're totally right but I'm guessing Ruby might be Jorg's first language and the scoping might seem obvious to him!
-
Jörg W Mittag over 7 years@AlexanderSuraphel: Actually, it was about my fifteenth language, although by the time I wrote that answer, I was probably up another dozen or so. I don't really keep track.