Ruby 顶级作用域中 self 与当前类的问题

匿名 · 2012年09月02日 · 最后由 funfriend 回复于 2012年09月04日 · 2201 次阅读

问题由来: 据《the book of ruby》 eval 相关章节。 eval 是 Object 的一个私有方法,可以在顶级作用域上用以下方式将其 public。

class Object
  public :eval
end

或直接 public :eval

于是奇怪的想法来了。

public 方法是 Module 的一个实例方法,在 Object 里是可以调用。 可是顶级作用域中,self 是 Object 的一个实例,怎么可以直接调用 public 呢?与当前类有关?

既然 Object 能用,一切对象都能用,所以 self 当然也能调用。

irb(main):018:0> self.method(:public).owner == self.singleton_class
=> true

试了下,只知道是在单键类中定义的

匿名 #3 · 2012年09月02日

#2 楼 @jjym 试了一下 self 的单件方法。

irb 中的

1.9.3-p194 :005 > self.singleton_methods false
 => [:to_s, :public, :private, :include, :context, :conf, :irb_quit, :exit, :quit, :irb_print_working_workspace, :irb_cwws, :irb_pwws, :cwws, :pwws, :irb_current_working_binding, :irb_print_working_binding, :irb_cwb, :irb_pwb, :irb_chws, :irb_cws, :chws, :cws, :irb_change_binding, :irb_cb, :cb, :workspaces, :irb_bindings, :bindings, :irb_pushws, :pushws, :irb_push_binding, :irb_pushb, :pushb, :irb_popws, :popws, :irb_pop_binding, :irb_popb, :popb, :source, :jobs, :fg, :kill, :help]
1.9.3-p194 :006 > obj=Object.new
 => #<Object:0x00000000a735a0> 
1.9.3-p194 :007 > obj.singleton_methods false
 => [] 

同样的语句在文本中也试了一下

self.singleton_methods false #-> [:to_s, :public, :private, :include]
Object.new.singleton_methods false #-> []

求权威解释

#3 楼 @funfriend irb 那个是因为 main Object 被混入 IRB 需要的模块了,所以多出很多方法

self.singleton_class.ancestors - Object.new.singleton_class.ancestors #-> [] 说明 main Object 的 singleton_class 没有混入模块。但是 singleton_methods 中有多出的方法。 并且重新定义了 to_s 但没有定 protect 和 extend。 所以有理由认为 main 对象是 ruby 解释器初始化时定义的这几个 singleton_methods

匿名 #5 · 2012年09月02日

#4 楼 @jjym 额,有道理。 其实我主要是想问,这里

self.singleton_methods false #-> [:to_s, :public, :private, :include]
Object.new.singleton_methods false #-> []

顶级作用域为什么要特殊化,混入上面这几个方法

#5 楼 @funfriend 大哥。。不特殊化的话你不就不能用这几个方法了。。因为顶级作用域是个对象内部。而且 to_s 的话能显示出这个对象很牛 x。这些方法不是 mix-in 的

匿名 #7 · 2012年09月04日

#6 楼 @jjym 好吧,我钻牛角尖了。。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册