Ruby local variable is undefined

41,778

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

Share:
41,778
Sergii Shevchyk
Author by

Sergii Shevchyk

Updated on February 04, 2020

Comments

  • Sergii Shevchyk
    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
    Adam Tolley about 10 years
    If 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
    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
    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.