Ruby 在类和对象方面非常一致。然而,当涉及到顶级方法声明时,该规则不知何故被打破了。例如,
$ puts self # => main
$ puts self.class # => Object
但是,在此 main
对象的上下文中声明的方法以某种方式可用作类 Object
的私有(private)方法。
这有什么合乎逻辑的解释吗?我知道这非常方便,因为这些方法显示为“独立函数”,但将其视为“就是这样”会破坏其他一致的规则,因为通常您必须在类的上下文中定义方法因为它是那个类的一个方法。但是,main
对象不是类 Object
,也根本不是类。
重新构建我的问题: 该方法在什么范围内在 ruby 的 REPL 中声明? {class Object/object main or module Kernel}
关于在 REPL 中声明的方法的私有(private)性质,请看下面的例子:
def my_method # "a method declared in REPL"
puts "method called"
end
# calling my_method in REPL aka top-level scope
my_method # => "method called"
[].my_method # => private method `my_method' called for []:Array (NoMethodError)
Array.my_method # => private method `my_method' called for Array:Class (NoMethodError)
问:如果my_method定义为Object类下的私有(private)方法,为什么self设置为main而不是Object类。如果有人说它不在私有(private)范围内,那么为什么我会收到上述错误?
最佳答案
虽然我不确定我是否完全理解这个问题,但我会尝试回答:
当你在 irb
中工作时,你实际上是在这样的环境中工作:
class Object
# you're here
end
因此,如果您在 REPL 中声明一个方法,您实际上是在 main
的类中声明它:
ruby-1.9.3-rc1 :001 > def foo; end
=> nil
ruby-1.9.3-rc1 :002 > self.class.public_methods.include?(:foo)
=> true
我不确定您是从哪里了解到那里定义的方法是类私有(private)的(但同样,我可能误解了这个问题)。
您在 irb
中的类包括 Kernel
模块,因此您可以访问它的功能(因为您在类中,所以出现作为独立函数,即使它们是常规方法):
ruby-1.9.3-rc1 :003 > self.class.included_modules
=> [Kernel]
这将使它与典型的 Ruby 行为保持一致,事实上,main
只是 Object 类中的 self
。
如果您调用 self
,您将收到 main
,因为这是指示通过检查执行此操作的方式。我们可以从 self
中删除 #to_s
方法并查看实际值:
ruby-1.9.3-p0 :001 > self
=> main
ruby-1.9.3-p0 :002 > class << self; remove_method :to_s; end
=> #<Class:#<Object:0x007fc08387af00>>
ruby-1.9.3-p0 :003 > self
=> #<Object:0x007fc08387af00 @prompt={:PROMPT_I=>"ruby-1.9.3-p0 :%03n > ", :PROMPT_S=>"ruby-1.9.3-p0 :%03n%l> ", :PROMPT_C=>"ruby-1.9.3-p0 :%03n > ", :PROMPT_N=>"ruby-1.9.3-p0 :%03n?> ", :RETURN=>" => %s \n", :AUTO_INDENT=>true}>
编辑:在继续之前,我认为您应该弄清楚您使用的是哪个 Ruby 版本,请参阅下面的 1.9.3 示例:
ruby-1.9.3-p0 :001 > def my_method
ruby-1.9.3-p0 :002?> puts "method called"
ruby-1.9.3-p0 :003?> end
=> nil
ruby-1.9.3-p0 :004 >
ruby-1.9.3-p0 :005 > [].my_method
method called
=> nil
ruby-1.9.3-p0 :006 > Array.my_method
method called
关于ruby - 关于 ruby 'main' 对象的不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11474610/