Ruby局部变量未定义

Ser*_*hyk 37 ruby local-variables

我有以下Ruby代码:

local_var = "Hello"

def hello
  puts local_var
end

hello
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

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

我一直认为局部变量不能从块外部,函数,闭包等访问.

但是现在我在文件中定义了局部变量,并尝试从INSIDE函数获取对同一文件的访问权限 .

我的理解有什么问题?

emr*_*azi 55

在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
Run Code Online (Sandbox Code Playgroud)

这些进入和离开点称为范围门.由于您通过方法定义通过Scope Gate输入,因此无法访问local_var内部hello方法.


您可以使用Scope Flattening概念通过这些门传递变量.

例如,def您可以使用而不是用于定义您的方法Module#define_method.

local_var = "Hello"

define_method :hello do
  puts local_var
end
Run Code Online (Sandbox Code Playgroud)

以同样的方式,您可以通过定义类,Class#New以便在通过类定义时范围不会更改.

local_var = 'test'

MyClass = Class.new do
  puts local_var #valid
end
Run Code Online (Sandbox Code Playgroud)

代替

class MyClass
  puts local_var #invalid
end
Run Code Online (Sandbox Code Playgroud)

Module#New如果要通过模块门传递局部变量,则应使用相同的方法.

示例取自Metaprogramming Ruby