我有以下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>'

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

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

我的理解有什么问题?

推荐答案

在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

这些进出点被称为范围门.由于您通过方法定义通过范围门进入,所以无法访问local_var inside 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.

Example is taken from Metaprogramming Ruby

Ruby相关问答推荐

Ruby错误-应为数组或字符串,已获取哈希

扫描不带空格的字符串中的单词

Ruby PKCS7:添加;\r〃;字节正在 destruct 解密

如何查询哪些RuboCop规则适用于文件?

Ruby:一个方法可以返回不同类型的对象吗?

RSpec 模拟对象示例

如何获取字符串中所有出现的 Ruby 正则表达式的匹配数据?

如何合并散列数组以获取值数组的散列

在Ruby中第一个=符号之后获取子字符串

Ruby 被空格分割

如何设置方法测试中使用的私有实例变量?

确定一个值是否存在于哈希数组中

Ruby,生成随机十六进制 colored颜色

如何在数组中找到出现次数最多的项目

如何在课堂上使用 Enumerable mixin?

如何在 Mac OS X Lion 中安装 Ruby 1.9.3?

通过 factory_girl 协会查找或创建记录

Ruby:使用 ENV 变量(如果存在)的最简洁方法,否则使用默认值

当我们导入 csv 数据时,如何消除UTF-8 中的无效字节序列

什么是 Ruby 1.9 标准 CSV 库?