在回答另一个问题时,我意识到以下程序并没有完全符合我的想法.
puts "test"
self.puts "test" # => private method `puts' called for main:Object (NoMethodError)
Run Code Online (Sandbox Code Playgroud)
这个例外让我感到惊讶,因为我一直认为顶级方法调用会被main对象实例解析,但事实并非如此.
谁是第一个电话的实际接收者,它是如何解决的?这是一个特殊规则,仅适用于顶级范围的方法调用吗?
这是一个很好的讨论,讨论了这个问题。
由Kernel提供的顶级方法自动包含在Object类中。这意味着内核方法将出现在所有内容中。
该错误private method 'puts' called for main:Object (NoMethodError)仅表示认沽证存在,但属于私有范围。
ree-1.8.7-2011.03 :001 > puts "test"
test
ree-1.8.7-2011.03 :004 > self.send(:puts, "hi" )
hi
Run Code Online (Sandbox Code Playgroud)
更新
内核方法没有魔术。没有范围跳跃或任何东西。我认为使用时范围的混乱线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
Run Code Online (Sandbox Code Playgroud)
通过使用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>
Run Code Online (Sandbox Code Playgroud)