2

IRB 是在 Ruby 中玩耍和测试事物的好方法。也可以使用脚本进行一些设置,如下所示:

require 'irb'

class Pirate
  def greet
    puts "Arrrrr, nice to meet ya"
  end
end

IRB.start # You can now instantiate Pirate in IRB

但是,我不清楚的一件事是执行此操作时的变量范围。如果我在之前添加这些行IRB.start

smithy     = Pirate.new
@blackbard = Pirate.new

...@blackbeard将在 IRB 中可用,但引用smithy将获得undefined local variable or method 'smithy' for main:Object.

为什么?

4

1 回答 1

6

用于评估代码的Binding设置在irb/workspace.rb:51(我在这里指的是 Ruby 1.9.3 rev 35410):

@binding = eval("def irb_binding; binding; end; irb_binding",
                TOPLEVEL_BINDING,
                __FILE__,
                __LINE__ - 3)

这意味着您的 IRB 会话与顶级方法中的代码在相同的上下文中运行。观察:

puts "Outer object ID: %d" % self.object_id
puts "Outer binding: " + binding.inspect
smithy     = Pirate.new
@blackbard = Pirate.new

def test
  puts "Inner object ID: %d" % self.object_id
  puts "Inner binding: " + binding.inspect
  p @blackbard
  p smithy
end
test

输出:

Outer object ID: 13230960
Outer binding: #<Binding:0x00000001c9aee0>
Inner object ID: 13230960
Inner binding: #<Binding:0x00000001c9acd8>
#<Pirate:0x00000001c9ada0>
/test.rb:18:in `test': undefined local variable or method `smithy' for main:Object (NameError)
    ...

请注意,对象上下文 ( self) 在函数内部和外部都是相同的。这是因为每个顶级方法都添加到全局main对象中。

另请注意,方法内部和外部的绑定不同。在 Ruby 中,每个方法都有自己的名称范围。这就是为什么您不能从 IRB 内部访问本地名称,而您可以访问实例变量的原因。

老实说,IRB 并不是 Ruby 软件中最辉煌的一块。我通常将Pry用于这种东西,你可以使用它:

require 'pry'
binding.pry

并拥有一个可以访问当前局部变量的会话。

于 2012-05-26T15:41:30.803 回答