Подтвердить что ты не робот

Локальная переменная Ruby имеет значение undefined

У меня есть следующий код 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>'

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

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

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

4b9b3361

Ответ 1

В Ruby локальные переменные доступны только в области, которую они определены. Всякий раз, когда вы вводите/оставляете класс, модуль или метод определяют вашу область видимости в 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 Gates. Поскольку вы входите через Scope Gate через определение метода, вы не можете получить доступ к local_var внутри метода hello.


Вы можете использовать концепцию Scope Flattening, чтобы передать свою переменную через эти ворота.

Например, вместо использования 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

Ответ 2

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