Локальная переменная Ruby не определена

У меня есть следующий код Ruby:

local_var = "Hello"

def hello
  puts local_var
end

hello

Я получаю следующую ошибку:

local_variables.rb:4:in 'hello': undefined local variable or method 'local_var' 
for main:Object (NameError) from local_variables.rb:7:in '<main>'

Я всегда думал, что локальные переменные недоступны извне блока, функции, закрытия и т. д.

но теперь я определил локальную переменную в файле и пытаюсь получить доступ из функции внутри один и тот же файл.

что не так с моим пониманием?

2 ответов


в локальных переменных Ruby доступны только в той области, в которой они определены. Всякий раз, когда вы входите/выходите из класса, модуля или метода definiton ваша область изменяется в Ruby.

например :

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

эти точки входа и выхода называются воротами области. Поскольку вы входите через Scope Gate через определение метода, вы не можете получить доступ к своему local_var внутри hello метод.


вы можете использовать концепцию сплющивания объема пропуск ваш переменная через эти ворота.

например, вместо использования def для определения вашего метода вы можете использовать Module#define_method.

local_var = "Hello"

define_method :hello do
  puts local_var
end

таким же образом вы можете определить свои классы через Class#New чтобы ваша область не изменялась при прохождении определения класса.

local_var = 'test'

MyClass = Class.new do
  puts local_var #valid
end

вместо

class MyClass
  puts local_var #invalid
end

таким же образом, вы должны использовать Module#New если вы хотите передать свои локальные переменные через ворота модуля.

пример взято из Метапрограммирование В Ruby


local_var локальная переменная. Локальные переменные являются локальными для области, в которой они определены. (Вот почему они под названием "локальные переменные", в конце концов!) Так, очевидно, с local_var определяется в области сценария, вы не можете получить к нему доступ в области метода.