Ruby全球范围

Nik*_* B. 6 ruby scope

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

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

这个例外让我感到惊讶,因为我一直认为顶级方法调用会被main对象实例解析,但事实并非如此.

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

mgu*_*mon 5

这是一个很好的讨论,讨论了这个问题。

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)