Misc #19304
openKernel vs Object documentation
Description
The restating of the problems raised in #19300, from scratch.
I believe it is rather a topic of community significance and would be happy if it is possible to discuss on dev-meeting, even if the outcome would probably "let's change RDoc in this or that way".
So, the problem statement:
-
Kernel
module defines two "types" of methods: private ones, that pretend to be global (likeputs
), but actually available from inside every object; and public ones (like#class
or#frozen?
) that are present in every object includingKernel
. - Since the beginning of times, docs provided an illusion that the second type of the methods belongs to
Object
class, which is, in fact, devoid of its own definitions, just includesKernel
. This was handled by special RDoc hack (which, basically, forcefully reattached definition of public methods if they are defined inKernel
, toObject
) - The RDoc hack was working in C code only, so after introduction of
kernel.rb
the illusion started to crumble: methods like#tap
,#then
,#class
are now documented as belonging toKernel
(breaking the tradition of public methods being documented inObject
) - This is all inconsistent and confusing, and I believe, adds to friction both for newcomers and curious investigators of the language!
Additionally, I believe:
- That the distinction of "two kinds of methods" is useful (saying from a practical experience with explaining Ruby while mentoring, writing articles, and discussing with colleagues)
- But, considering everything, I agree with what @Eregon (Benoit Daloze) and @nobu (Nobuyoshi Nakada) say in #19300: pretending that methods belong not to the module they really belong to is not the optimal way to document things!
So, the options I see (save for "do nothing and let things sort themselves somehow"):
- Change Ruby's implementation so public methods would really belong to
Object
. Actually, I don't believe anybody would agree to experiment on this scale, so just listing it here for completeness. - Just remove the RDoc hack; all methods would belong to
Kernel
, and maybe some introductory free-form text will instruct that they are different. Pro: Easy to do. Contra: TheKernel
docs would be super-confusing. - Continue to maintain the hack in RDoc and extend it to
kernel.rb
(so methods like#clone
and#frozen?
would be still inObject
). Pro: Relatively easy to do, will maintain structure many people used to. Contra: This is still a lie, methods belong toKernel
, notObject
. - Adjust RDoc to a) be able to separately list public and private methods in two different lists, and add intro for
Kernel
explaining how to treat those. Pro: Probably the best correspondence to reality? Contra: Not sure how easy it is to change RDoc this way; and other renderers (like ruby-doc.com and rubyapi.org) would need to adjust themselves.
So far, (4) looks the most reasonable (if (1) is 100% impossible, that is!)
Updated by austin (Austin Ziegler) almost 2 years ago
I think that (2) looks promising if sections are used (https://ruby.github.io/rdoc/RDoc/Markup.html#class-RDoc::Markup-label-Sections) in the documentation, although I must admit that I’ve never used those. It would absolutely need to be used consistently in both C and kernel.rb
method definitions.
Updated by nobu (Nobuyoshi Nakada) almost 2 years ago
Is the option 3 like this?
https://github.com/ruby/rdoc/pull/961
Updated by sawa (Tsuyoshi Sawada) almost 2 years ago
Can you expand on why option 2 would be super-confusing? I think that option is the best.
Updated by zverok (Victor Shepelev) almost 2 years ago
Can you expand on why option 2 would be super-confusing? I think that option is the best.
Because those are two different categories of methods (as this and the previous ticket discuss in detail), and having them in one mixed list makes it hard to distinguish "global methods" (aka Kernel's private) from "public methods that every object has".
From every Ruby documentation user, it doesn't matter much that they are defined in the same module, but it does matter much that methods like puts
or require
aren't homogenous with methods like class
, frozen?
or clone
.
That, I believe, was the reason for the initial RDoc decision to pretend public methods are belonging to Object
.
Updated by sawa (Tsuyoshi Sawada) almost 2 years ago
@zverok (Victor Shepelev) The Kernel
page is entirely broken anyway from its first sentence:
The
Kernel
module is included by classObject
, so its methods are available in every Ruby object.
the latter half of which is not true since the introduction of BasicObject
, and what it claims to be "Public Instance Methods" are not public. It is confusing in the current state.
It just needs to be entirely fixed. Fixing this and describing public and private methods correctly would not be confusing.
Updated by zverok (Victor Shepelev) almost 2 years ago
Fixing this and describing public and private methods correctly would not be confusing.
This is option (4) of my initial list, I believe.
Option (2) — the easiest and the least desirable of them — is just to dump everything into Kernel without trying to separate the two kinds.
(If you meant only fixing each individual method docs, without separating methods in two lists, it will still be bad. The list of methods that class/object has is a significant part of the docs navigation. Having puts
and class
in the same homogenous list is bad.)
Updated by matheusrich (Matheus Richard) almost 2 years ago
Thanks for voicing that, @zverok (Victor Shepelev)! I always found this confusing (i.e., some methods being defined in Kernel, not in Object), and I'd love to see the docs reflect that in some form. (1) feels like the right thing to do, so what are the roadblocks? Backward compatibility? After that, I think (4) is the way to go.
Updated by mame (Yusuke Endoh) over 1 year ago
Discussed at the dev meeting. In conclusion, Option 4 looks good.
- Stop that "hack" of RDoc; all methods defined in Kernel should be listed in the Kernel documentation.
- rdoc should clearly distinguish between module functions and others. (This is not limited to Kernel)
- It is okay to state, at the beginning of the Kernel documentation, that Kernel's module functions are a global function in effect.
The current RDoc does not appear to handle module functions correctly. For example, Math.acos
is listed as "Public Class Methods", which would not be appropriate. If this is fixed, the problem of this ticket should be also fixed automatically, we thought.
For the record, matz stated that he does not feel the need to distinguish between global functions (e.g., fork and exit) and others (e.g., is_a? and kind_of?), either in the implementation or in the documentation. He is fine with all methods being presented in one list. But he was not opposed to the above handling.
Updated by hsbt (Hiroshi SHIBATA) 7 months ago
- Status changed from Open to Assigned