在回答另一个问题时,我意识到以下程序并没有完全符合我的想法。
puts "test"
self.puts "test" # => private method `puts' called for main:Object (NoMethodError)
异常让我感到惊讶,因为我一直认为顶级方法调用将由main
对象实例解决,但似乎并非如此。
谁是第一个电话的实际接收者,它是如何解决的?这是一个特殊规则,仅适用于顶级范围的方法调用吗?
答案 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>