为什么local_variables返回尚未分配的局部变量?

时间:2013-03-28 07:27:00

标签: ruby

为什么local_variables会返回尚未分配的局部变量(在调用local_variables后分配)?

a = 2
@aa = 1
# a = b # this will raise an error.
puts "local: #{ local_variables }"
puts "instance: #{ instance_variables }"

b = 2
@bb = 2
puts "local: #{ local_variables }"
puts "instance: #{ instance_variables }"

结果:

local: [:a, :b]
instance: [:@aa]
local: [:a, :b]
instance: [:@aa, :@bb]

我期望的是像instance_variables这样的行为,它只返回那一刻已经分配过的变量。

2 个答案:

答案 0 :(得分:1)

Kernel#local_variables列出当前范围内的所有局部变量,包括那些可能尚未赋值的局部变量。 MRI解析每个范围内的locals变量,并在代码本身(例如下面的puts local_variables.inspect)运行之前声明它们,因此即使在local_variables被调用之前它们也会出现,然后才定义这些变量

但请注意,defined?仍会为调用nil时尚未分配的变量返回local_variables

$ cat /tmp/locals
#!/usr/bin/env ruby

a = 5
puts local_variables.inspect
puts defined?(a)
puts (defined?(b) || "[undefined]")
b = 10
puts defined?(b)

def foo
  c = 15
  puts local_variables.inspect
  d = 20
end
foo

$ ruby /tmp/locals
[:a, :b]
local-variable
[undefined]
local-variable
[:c, :d]

答案 1 :(得分:1)

Ruby creates local variables at compile time。实例变量明确绑定到实例,并且可以轻松访问。但是,b可以是:

  1. 方法调用
  2. self.b
  3. 本地变量b
  4. 看看Brian Candler's response here (Google cache)。这也是您无法在运行时使用eval创建局部变量的原因。