Ruby 吐槽一下 ruby 的文档

dfang · 2012年09月23日 · 最后由 dfang 回复于 2012年09月23日 · 2922 次阅读

为什么 ruby 的文档有很多重复的,ruby-doc 竟然貌似还不是官方的(看网站底部的说明),而是私人维护的 .....

有些地方错没错就不知道了,但是这些肯定重复了

http://www.ruby-doc.org/core-1.9.3/Kernel.html fork [{ block }] → fixnum or nil

http://www.ruby-doc.org/core-1.9.3/Kernel.html method → symbol

http://ruby-doc.org/core-1.8.7/Kernel.html autoload(module, filename) => nil

http://ruby-doc.org/core-1.9.3/Object.html is_a?(class) → true or false

而且为什么没有哪个文档标明哪些方法是 public 的,哪些是 private 的.....

另外顺便问下这个问题 http://stackoverflow.com/questions/11632416/if-self-is-always-the-implied-receiver-in-ruby-why-doesnt-self-puts-work

但是我认为答案说得不对啊,因为 puts is a public method , method(:puts).owner.public_methods.grep /puts/ returns [:puts] .

MRI ruby 1.93p194

#1 楼 @alvin2ye 看了的 这个不见得比 ruby-doc 好 其实我是想问问为什么出现那种情况,给 james 发了邮件,他的回复是:

I really don't know. I thought it had something to do with aliasing, or with classes that are defined over multiple files, but I was just looking at some source code and now I'm not sure.

In some cases it does appear to be a case of one method simply aliased to another, but then we have "fork" duplicated.

That's a good question. Rdoc gives the option of including all methods, public and private (the default is to omit private methods).

ruby-doc is generated using the -all switch so all methods are included, but it apparently does not add anything to method descriptions to tell you visibility.

This is probably something that would have to be added by whomever maintains the rdoc code (Eric Hodel, perhaps).

这个很好理解嘛,看下面的例子就明白了:

[28] pry(main)> module Hello
[28] pry(main)*   def hello
[28] pry(main)*   end  
[28] pry(main)* end  
=> nil
[32] pry(main)> class World
[32] pry(main)*   include Hello
[32] pry(main)*   private :hello
[32] pry(main)* end  
=> World
[33] pry(main)> World.new.hello
NoMethodError: private method `hello' called for #<World:0x00000001d10050>
from (pry):58:in `__pry__'
[34] pry(main)> 

对于 Kernel 这个 module 来说 puts 是 public 的,但是对于 Object 这个对象来说,puts 是私有方法。

在方法查找的时候先找到 Object#puts,然后判断为私有,最后抛异常。

我猜测 Ruby 内部应该大概这么实现的:

class Object
  include Kernel
  private *Kernel.methods
end

@hooopo 你说的这个我理解啊,你这举的例子不跟那个链接的答案差不多嘛,都是说的一个道理,我想问的是 puts 是 public method , 不能用这个例子来解释把

method(:puts).owner.public_methods.grep /puts/ => [:puts]

#4 楼 @dfang 你对method(:puts).owner.public_methods.grep /puts/这段代码没理解啊 这段代码只能说明 puts 是 Kernel 的 public 方法。

Object.new.private_methods.grep /puts/
=> [:puts]

上面说明 puts 是 Object 的私有方法。

而你在调用 xx.puts 的时候根据方法查找顺序,是调用的 Object#puts,和 Kernel 那个就没任何关系。。

@hooopo 嗯 的确,忘记了方法的查找机制了 , thx ! self.class.ancestors => [Object, Kernel, BasicObject]

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