Ruby全球范围

时间:2012-03-28 16:24:54

标签: ruby scope

在回答另一个问题时,我意识到以下程序并没有完全符合我的想法。

puts "test"
self.puts "test"  # => private method `puts' called for main:Object (NoMethodError)

异常让我感到惊讶,因为我一直认为顶级方法调用将由main对象实例解决,但似乎并非如此。

谁是第一个电话的实际接收者,它是如何解决的?这是一个特殊规则,仅适用于顶级范围的方法调用吗?

1 个答案:

答案 0 :(得分:5)

这是一个讨论这个问题的good discussion

Kernel提供的顶级方法会自动包含在 Object 类中。这意味着内核方法将出现在所有内容中。

错误private method 'puts' called for main:Object (NoMethodError)只是声明存在put但是是私有范围的。

ree-1.8.7-2011.03 :001 > puts "test"
test
ree-1.8.7-2011.03 :004 > self.send(:puts, "hi" )
hi

<强>更新

内核方法没有神奇之处。没有范围跳跃或任何东西。我认为使用self时范围的混淆线。您无法使用self访问私有方法。

class PutsTest

  def success_puts
    private_puts
  end

  def failed_puts
    # trying to access a private method from self
    self.private_puts
  end

  private

  def private_puts
   puts 'hi'
  end
end

通过使用 self ,您正在将范围从调用 PutsTest 中的方法更改为从 PutsTest

外部调用>
ree-1.8.7-2011.03 :095 > test = PutsTest.new
ree-1.8.7-2011.03 :096 > test.success_puts
hi
ree-1.8.7-2011.03 :097 > test.failed_puts
NoMethodError: private method `private_puts' called for #<PutsTest:0xd62c48>