Ruby kernel 中的 print 是私有方法,所有对象咋访问的

anleb · 2012年07月27日 · 最后由 silkbaby 回复于 2014年10月10日 · 3571 次阅读

如题,我们追溯类的祖先, Object.ancestor # [Object,Kernel,BaseObject]

Kernel.private_instance_methods.grep(/pri/)

可以看到 print 是私有方法,object 类包含 kernel,它是怎么实现让对象可以访问私有方法 print 的?

共收到 16 条回复

p self,self.class 看看 当前执行环境就是在一个 Object 内部,所以直接可以访问私有方法 几乎每本 Ruby 教材上都讲了

私有原则:私有方法在不指定接收者对象的情况下可以被调用,所以子类对象可以调用父类的私有方法。 举例如 method_1 为私有方法, a.method_1 or self.method_1 调用会失败,但 method_1 可被正常调用。 这和 C++ 或者 Java 等语言不太一样。

#1 楼 @jjym 豁然开朗,谢谢

#1 楼 @jjym 好像没那么简单,

#5 楼 @jjym #2 楼 @tech_blogbin 2 楼有点意思的,说的差不多了 module A def ask “abc” end end

class B include A def ask super end end

是不是内核私有方法是不是都是这样实现的。

#6 楼 @Anleb 为什么还要在定义个?而且你这方法也不是私有的。

#7 楼 @jjym 那 object 包含 kernal 怎么调用私有方法

#8 楼 @Anleb 和你在 Object 里定义的私有方法调用一样。

这个问题没人会吗

#11 楼 @Anleb

我觉得你以前是不是学过某些静态语言, 被 private 这个单词含义的给欺骗了, 的确, private 是无法在类的外部被调用, 但是在类继承体系内, private 方法是可以被调用的, 而且只能通过一种方式, 那就是类似于全局函数一样, 隐式的通过 self 来调用, 它就等价于 self.a_private_method, 但是你就是不能用 self, 这也意味着, 他总是以当前所在类为 self, 如果当前类没有实现, 那就会追溯祖先类实现.

说实话, 你的标题问题我没有太明白, 如果你是觉得 print 为什么会被调用, 那我告诉你, 所谓的顶层空间, 他就是在 object 类的内部. 如果你觉得为什么可以使用 file_object.print "...", 那是因为这个 print 不是 kernel.print, 这是在 IO 类实现的另一个 print. 不要混为一谈.

#12 楼 @zw963 以前搞过汇编和 c#,但是我无法解释 ''' class A print "aaaa" end ''' 按照我们的思路,这里 print 的接受者是 self,也就是 A,你刚才说的 那是因为这个 print 不是 kernel.print, 这是在 IO 类实现的另一个 print. 不要混为一谈. 能具体点吗

#13 楼 @Anleb

我晕, 你怎么还是糊涂, 我刚才给你了个两个答案, 那是因为我不知道你要问什么.

你上面这个问题, 那就是 Kernel.print. 因为 class A 里面没有定义 print 方法, 它就会在祖先类寻找, 最后在 Object 下面发现 print. 明白了吗?

#14 楼 @zw963 明白了。。。private 不需要带接受者

阿斯顿发送到撒打发斯蒂芬

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