[ruby-core:111579] [Ruby master Feature#19300] Move public objects from Kernel to Object

Issue #19300 has been reported by zverok (Victor Shepelev). ---------------------------------------- Feature #19300: Move public objects from Kernel to Object https://bugs.ruby-lang.org/issues/19300 * Author: zverok (Victor Shepelev) * Status: Open * Priority: Normal ---------------------------------------- In my understanding, `Kernel` is a container for methods that are perceived as "global", and are available inside every objects as its private methods, like `puts` ```ruby class A def foo = puts "foo" end a = A.new a.foo # prints "foo" a.puts 'bar' # private method `puts' called for #<A:0x00007f39a683db28> (NoMethodError) ``` There are, though, exactly three (if I am not missing something) methods that, **according to documentation**, break this intuition and belong to [Kernel](https://docs.ruby-lang.org/en/master/Kernel.html): * `clone` * `tap` * `then` All those methods are public method for a receiver, and they mostly make sense with an explicit receiver. The most confusing of them is `#clone`, which is close cousin of `#dup`, but it is [Kernel#clone](https://docs.ruby-lang.org/en/master/Kernel.html#method-i-clone) and [Object#dup](https://docs.ruby-lang.org/en/master/Object.html#method-i-dup). This state of things is mostly harmless in practical code, but very inconvenient for teaching, reasoning about the meaning of modules and objects, and lookup for documentation. **But**, in the description above, **according to documentation** is important statement. Because according to introspection, method definitions are spread differently: ```ruby puts "Public" Object.new .then { |o| o.methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } puts puts "Private:" Object.new .then { |o| o.private_methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } ``` Output: ``` Public Kernel: !~, <=>, ===, class, clone, define_singleton_method, display, dup, enum_for, eql?, extend, freeze, frozen?, hash, inspect, instance_of?, instance_variable_defined?, instance_variable_get, instance_variable_set, instance_variables, is_a?, itself, kind_of?, method, methods, nil?, object_id, private_methods, protected_methods, public_method, public_methods, public_send, remove_instance_variable, respond_to?, send, singleton_class, singleton_method, singleton_methods, tap, then, to_enum, to_s, yield_self BasicObject: !, !=, ==, __id__, __send__, equal?, instance_eval, instance_exec Private: Kernel: Array, Complex, Float, Hash, Integer, Rational, String, __callee__, __dir__, __method__, `, abort, at_exit, autoload, autoload?, binding, block_given?, caller, caller_locations, catch, eval, exec, exit, exit!, fail, fork, format, gem, gem_original_require, gets, global_variables, initialize_clone, initialize_copy, initialize_dup, iterator?, lambda, load, local_variables, loop, open, p, pp, print, printf, proc, putc, puts, raise, rand, readline, readlines, require, require_relative, respond_to_missing?, select, set_trace_func, sleep, spawn, sprintf, srand, syscall, system, test, throw, trace_var, trap, untrace_var, warn BasicObject: initialize, method_missing, singleton_method_added, singleton_method_removed, singleton_method_undefined ``` E.g., internally, `Object` doesn't have _any_ method defined, and is just a `BasicObject` with `Kernel` included. So, there are three questions/proposals: 1. Does this disposition has some internal sense, or it is more of a historical thing? 2. Can it be changed so that public methods belonged to `Object` instead of `Kernel`? 3. If the answer to (2) is "no", can at least docs for `clone`, `tap` and `then` be adjusted to follow other public methods in pretending they are `Object`'s features? -- https://bugs.ruby-lang.org/

Issue #19300 has been updated by hmdne (hmdne -). In particular, Delegator works in an interesting way by: 1. Inheriting from BasicObject 2. Duping the Kernel module (as k) 3. Undefining some methods from k 4. Including k So, for this particular purpose, moving methods from Kernel to Object may break compatibility. See: https://github.com/ruby/delegate/blob/master/lib/delegate.rb#L44-L57 ---------------------------------------- Feature #19300: Move public objects from Kernel to Object https://bugs.ruby-lang.org/issues/19300#change-100946 * Author: zverok (Victor Shepelev) * Status: Open * Priority: Normal ---------------------------------------- In my understanding, `Kernel` is a container for methods that are perceived as "global", and are available inside every objects as its private methods, like `puts` ```ruby class A def foo = puts "foo" end a = A.new a.foo # prints "foo" a.puts 'bar' # private method `puts' called for #<A:0x00007f39a683db28> (NoMethodError) ``` There are, though, exactly three (if I am not missing something) methods that, **according to documentation**, break this intuition and belong to [Kernel](https://docs.ruby-lang.org/en/master/Kernel.html): * `clone` * `tap` * `then` All those methods are public method for a receiver, and they mostly make sense with an explicit receiver. The most confusing of them is `#clone`, which is close cousin of `#dup`, but it is [Kernel#clone](https://docs.ruby-lang.org/en/master/Kernel.html#method-i-clone) and [Object#dup](https://docs.ruby-lang.org/en/master/Object.html#method-i-dup). This state of things is mostly harmless in practical code, but very inconvenient for teaching, reasoning about the meaning of modules and objects, and lookup for documentation. **But**, in the description above, **according to documentation** is important statement. Because according to introspection, method definitions are spread differently: ```ruby puts "Public" Object.new .then { |o| o.methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } puts puts "Private:" Object.new .then { |o| o.private_methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } ``` Output: ``` Public Kernel: !~, <=>, ===, class, clone, define_singleton_method, display, dup, enum_for, eql?, extend, freeze, frozen?, hash, inspect, instance_of?, instance_variable_defined?, instance_variable_get, instance_variable_set, instance_variables, is_a?, itself, kind_of?, method, methods, nil?, object_id, private_methods, protected_methods, public_method, public_methods, public_send, remove_instance_variable, respond_to?, send, singleton_class, singleton_method, singleton_methods, tap, then, to_enum, to_s, yield_self BasicObject: !, !=, ==, __id__, __send__, equal?, instance_eval, instance_exec Private: Kernel: Array, Complex, Float, Hash, Integer, Rational, String, __callee__, __dir__, __method__, `, abort, at_exit, autoload, autoload?, binding, block_given?, caller, caller_locations, catch, eval, exec, exit, exit!, fail, fork, format, gem, gem_original_require, gets, global_variables, initialize_clone, initialize_copy, initialize_dup, iterator?, lambda, load, local_variables, loop, open, p, pp, print, printf, proc, putc, puts, raise, rand, readline, readlines, require, require_relative, respond_to_missing?, select, set_trace_func, sleep, spawn, sprintf, srand, syscall, system, test, throw, trace_var, trap, untrace_var, warn BasicObject: initialize, method_missing, singleton_method_added, singleton_method_removed, singleton_method_undefined ``` E.g., internally, `Object` doesn't have _any_ method defined, and is just a `BasicObject` with `Kernel` included. So, there are three questions/proposals: 1. Does this disposition has some internal sense, or it is more of a historical thing? 2. Can it be changed so that public methods belonged to `Object` instead of `Kernel`? 3. If the answer to (2) is "no", can at least docs for `clone`, `tap` and `then` be adjusted to follow other public methods in pretending they are `Object`'s features? -- https://bugs.ruby-lang.org/

Issue #19300 has been updated by Eregon (Benoit Daloze). My tip is never trust the docs regarding what method is where: ``` irb(main):001:0> self.method :clone => #<Method: Object(Kernel)#clone(freeze: ...) <internal:kernel>:47> irb(main):002:0> self.method :dup => #<Method: Object(Kernel)#dup()> ``` (on ruby 3.1.3) So it's an issue of RDoc. Probably makes more sense at https://github.com/ruby/rdoc. I think we should not include Kernel methods at https://docs.ruby-lang.org/en/master/Object.html, Object and Kernel should be on separate pages because that is the truth. ---------------------------------------- Feature #19300: Move public objects from Kernel to Object https://bugs.ruby-lang.org/issues/19300#change-100962 * Author: zverok (Victor Shepelev) * Status: Open * Priority: Normal ---------------------------------------- In my understanding, `Kernel` is a container for methods that are perceived as "global", and are available inside every objects as its private methods, like `puts` ```ruby class A def foo = puts "foo" end a = A.new a.foo # prints "foo" a.puts 'bar' # private method `puts' called for #<A:0x00007f39a683db28> (NoMethodError) ``` There are, though, exactly three (if I am not missing something) methods that, **according to documentation**, break this intuition and belong to [Kernel](https://docs.ruby-lang.org/en/master/Kernel.html): * `clone` * `tap` * `then` All those methods are public method for a receiver, and they mostly make sense with an explicit receiver. The most confusing of them is `#clone`, which is close cousin of `#dup`, but it is [Kernel#clone](https://docs.ruby-lang.org/en/master/Kernel.html#method-i-clone) and [Object#dup](https://docs.ruby-lang.org/en/master/Object.html#method-i-dup). This state of things is mostly harmless in practical code, but very inconvenient for teaching, reasoning about the meaning of modules and objects, and lookup for documentation. **But**, in the description above, **according to documentation** is important statement. Because according to introspection, method definitions are spread differently: ```ruby puts "Public" Object.new .then { |o| o.methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } puts puts "Private:" Object.new .then { |o| o.private_methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } ``` Output: ``` Public Kernel: !~, <=>, ===, class, clone, define_singleton_method, display, dup, enum_for, eql?, extend, freeze, frozen?, hash, inspect, instance_of?, instance_variable_defined?, instance_variable_get, instance_variable_set, instance_variables, is_a?, itself, kind_of?, method, methods, nil?, object_id, private_methods, protected_methods, public_method, public_methods, public_send, remove_instance_variable, respond_to?, send, singleton_class, singleton_method, singleton_methods, tap, then, to_enum, to_s, yield_self BasicObject: !, !=, ==, __id__, __send__, equal?, instance_eval, instance_exec Private: Kernel: Array, Complex, Float, Hash, Integer, Rational, String, __callee__, __dir__, __method__, `, abort, at_exit, autoload, autoload?, binding, block_given?, caller, caller_locations, catch, eval, exec, exit, exit!, fail, fork, format, gem, gem_original_require, gets, global_variables, initialize_clone, initialize_copy, initialize_dup, iterator?, lambda, load, local_variables, loop, open, p, pp, print, printf, proc, putc, puts, raise, rand, readline, readlines, require, require_relative, respond_to_missing?, select, set_trace_func, sleep, spawn, sprintf, srand, syscall, system, test, throw, trace_var, trap, untrace_var, warn BasicObject: initialize, method_missing, singleton_method_added, singleton_method_removed, singleton_method_undefined ``` E.g., internally, `Object` doesn't have _any_ method defined, and is just a `BasicObject` with `Kernel` included. So, there are three questions/proposals: 1. Does this disposition has some internal sense, or it is more of a historical thing? 2. Can it be changed so that public methods belonged to `Object` instead of `Kernel`? 3. If the answer to (2) is "no", can at least docs for `clone`, `tap` and `then` be adjusted to follow other public methods in pretending they are `Object`'s features? -- https://bugs.ruby-lang.org/

Issue #19300 has been updated by nobu (Nobuyoshi Nakada). Status changed from Open to Third Party's Issue This is an issue of RDoc. RDoc replaces `rb_mKernel` with `rb_cObject` (= `Object`) internally, but it seems not working in some cases (maybe in `kernel.rb`?). There is no visibility differences between `Kernel` and `Object`. ---------------------------------------- Feature #19300: Move public objects from Kernel to Object https://bugs.ruby-lang.org/issues/19300#change-100964 * Author: zverok (Victor Shepelev) * Status: Third Party's Issue * Priority: Normal ---------------------------------------- In my understanding, `Kernel` is a container for methods that are perceived as "global", and are available inside every objects as its private methods, like `puts` ```ruby class A def foo = puts "foo" end a = A.new a.foo # prints "foo" a.puts 'bar' # private method `puts' called for #<A:0x00007f39a683db28> (NoMethodError) ``` There are, though, exactly three (if I am not missing something) methods that, **according to documentation**, break this intuition and belong to [Kernel](https://docs.ruby-lang.org/en/master/Kernel.html): * `clone` * `tap` * `then` All those methods are public method for a receiver, and they mostly make sense with an explicit receiver. The most confusing of them is `#clone`, which is close cousin of `#dup`, but it is [Kernel#clone](https://docs.ruby-lang.org/en/master/Kernel.html#method-i-clone) and [Object#dup](https://docs.ruby-lang.org/en/master/Object.html#method-i-dup). This state of things is mostly harmless in practical code, but very inconvenient for teaching, reasoning about the meaning of modules and objects, and lookup for documentation. **But**, in the description above, **according to documentation** is important statement. Because according to introspection, method definitions are spread differently: ```ruby puts "Public" Object.new .then { |o| o.methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } puts puts "Private:" Object.new .then { |o| o.private_methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } ``` Output: ``` Public Kernel: !~, <=>, ===, class, clone, define_singleton_method, display, dup, enum_for, eql?, extend, freeze, frozen?, hash, inspect, instance_of?, instance_variable_defined?, instance_variable_get, instance_variable_set, instance_variables, is_a?, itself, kind_of?, method, methods, nil?, object_id, private_methods, protected_methods, public_method, public_methods, public_send, remove_instance_variable, respond_to?, send, singleton_class, singleton_method, singleton_methods, tap, then, to_enum, to_s, yield_self BasicObject: !, !=, ==, __id__, __send__, equal?, instance_eval, instance_exec Private: Kernel: Array, Complex, Float, Hash, Integer, Rational, String, __callee__, __dir__, __method__, `, abort, at_exit, autoload, autoload?, binding, block_given?, caller, caller_locations, catch, eval, exec, exit, exit!, fail, fork, format, gem, gem_original_require, gets, global_variables, initialize_clone, initialize_copy, initialize_dup, iterator?, lambda, load, local_variables, loop, open, p, pp, print, printf, proc, putc, puts, raise, rand, readline, readlines, require, require_relative, respond_to_missing?, select, set_trace_func, sleep, spawn, sprintf, srand, syscall, system, test, throw, trace_var, trap, untrace_var, warn BasicObject: initialize, method_missing, singleton_method_added, singleton_method_removed, singleton_method_undefined ``` E.g., internally, `Object` doesn't have _any_ method defined, and is just a `BasicObject` with `Kernel` included. So, there are three questions/proposals: 1. Does this disposition has some internal sense, or it is more of a historical thing? 2. Can it be changed so that public methods belonged to `Object` instead of `Kernel`? 3. If the answer to (2) is "no", can at least docs for `clone`, `tap` and `then` be adjusted to follow other public methods in pretending they are `Object`'s features? -- https://bugs.ruby-lang.org/

Issue #19300 has been updated by zverok (Victor Shepelev). @Eregon
My tip is never trust the docs regarding what method is where
Thanks, as a person that tries to maintain and update the docs for each version, I am well aware of it. The initial ticket text also mentions this:
But, in the description above, according to documentation is important statement. Because according to introspection, method definitions are spread differently
So it's an issue of RDoc.
Well, I wouln't say it is an issue: it is a [deliberate decision](https://github.com/ruby/rdoc/blob/017bb9fa496ee0e0959facba694a053008d1ecb0/l...): Treat all public methods of `Kernel` as if they belong to `Object`. Which seems to be handling that old discrepancy of "what is implied" (`Kernel` is for private methods that pretend to be "global", `Object` is for public methods, common for each object) and "how it is implemented" (all methods are belonging to Kernel). Actually, the three problematic methods got to `Kernel`s docs (skipping this RDoc trick) when they were extracted into [`kernel.rb`](https://github.com/ruby/ruby/blob/master/kernel.rb). Oh, and looking closer, the same problem is related to `#class` and `#frozen?`. If we'll look at [2.7 Kernel docs](https://docs.ruby-lang.org/en/2.7.0/Kernel.html) (before `kernel.rb` was introduced), everything was fine and public `Object` methods belonged to `Object` in docs. ---------------------------------------- Feature #19300: Move public objects from Kernel to Object https://bugs.ruby-lang.org/issues/19300#change-100965 * Author: zverok (Victor Shepelev) * Status: Third Party's Issue * Priority: Normal ---------------------------------------- In my understanding, `Kernel` is a container for methods that are perceived as "global", and are available inside every objects as its private methods, like `puts` ```ruby class A def foo = puts "foo" end a = A.new a.foo # prints "foo" a.puts 'bar' # private method `puts' called for #<A:0x00007f39a683db28> (NoMethodError) ``` There are, though, exactly three (if I am not missing something) methods that, **according to documentation**, break this intuition and belong to [Kernel](https://docs.ruby-lang.org/en/master/Kernel.html): * `clone` * `tap` * `then` All those methods are public method for a receiver, and they mostly make sense with an explicit receiver. The most confusing of them is `#clone`, which is close cousin of `#dup`, but it is [Kernel#clone](https://docs.ruby-lang.org/en/master/Kernel.html#method-i-clone) and [Object#dup](https://docs.ruby-lang.org/en/master/Object.html#method-i-dup). This state of things is mostly harmless in practical code, but very inconvenient for teaching, reasoning about the meaning of modules and objects, and lookup for documentation. **But**, in the description above, **according to documentation** is important statement. Because according to introspection, method definitions are spread differently: ```ruby puts "Public" Object.new .then { |o| o.methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } puts puts "Private:" Object.new .then { |o| o.private_methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } ``` Output: ``` Public Kernel: !~, <=>, ===, class, clone, define_singleton_method, display, dup, enum_for, eql?, extend, freeze, frozen?, hash, inspect, instance_of?, instance_variable_defined?, instance_variable_get, instance_variable_set, instance_variables, is_a?, itself, kind_of?, method, methods, nil?, object_id, private_methods, protected_methods, public_method, public_methods, public_send, remove_instance_variable, respond_to?, send, singleton_class, singleton_method, singleton_methods, tap, then, to_enum, to_s, yield_self BasicObject: !, !=, ==, __id__, __send__, equal?, instance_eval, instance_exec Private: Kernel: Array, Complex, Float, Hash, Integer, Rational, String, __callee__, __dir__, __method__, `, abort, at_exit, autoload, autoload?, binding, block_given?, caller, caller_locations, catch, eval, exec, exit, exit!, fail, fork, format, gem, gem_original_require, gets, global_variables, initialize_clone, initialize_copy, initialize_dup, iterator?, lambda, load, local_variables, loop, open, p, pp, print, printf, proc, putc, puts, raise, rand, readline, readlines, require, require_relative, respond_to_missing?, select, set_trace_func, sleep, spawn, sprintf, srand, syscall, system, test, throw, trace_var, trap, untrace_var, warn BasicObject: initialize, method_missing, singleton_method_added, singleton_method_removed, singleton_method_undefined ``` E.g., internally, `Object` doesn't have _any_ method defined, and is just a `BasicObject` with `Kernel` included. So, there are three questions/proposals: 1. Does this disposition has some internal sense, or it is more of a historical thing? 2. Can it be changed so that public methods belonged to `Object` instead of `Kernel`? 3. If the answer to (2) is "no", can at least docs for `clone`, `tap` and `then` be adjusted to follow other public methods in pretending they are `Object`'s features? -- https://bugs.ruby-lang.org/

Issue #19300 has been updated by Eregon (Benoit Daloze). Yeah, and moving a method between C and Ruby like that is an implementation detail and should definitely not change on which page of the docs a method appears on. Hence, it's 100% a bug of RDoc, it was a mistake to show Kernel methods on Object.html, I think now it's obviously clear. Let's fix it. (Alternatively one could add more hacks into RDoc to also treat those Kernel methods in kernel.rb as "Object methods", but that seems way too big a hack, isn't it?) ---------------------------------------- Feature #19300: Move public objects from Kernel to Object https://bugs.ruby-lang.org/issues/19300#change-100966 * Author: zverok (Victor Shepelev) * Status: Third Party's Issue * Priority: Normal ---------------------------------------- In my understanding, `Kernel` is a container for methods that are perceived as "global", and are available inside every objects as its private methods, like `puts` ```ruby class A def foo = puts "foo" end a = A.new a.foo # prints "foo" a.puts 'bar' # private method `puts' called for #<A:0x00007f39a683db28> (NoMethodError) ``` There are, though, exactly three (if I am not missing something) methods that, **according to documentation**, break this intuition and belong to [Kernel](https://docs.ruby-lang.org/en/master/Kernel.html): * `clone` * `tap` * `then` All those methods are public method for a receiver, and they mostly make sense with an explicit receiver. The most confusing of them is `#clone`, which is close cousin of `#dup`, but it is [Kernel#clone](https://docs.ruby-lang.org/en/master/Kernel.html#method-i-clone) and [Object#dup](https://docs.ruby-lang.org/en/master/Object.html#method-i-dup). This state of things is mostly harmless in practical code, but very inconvenient for teaching, reasoning about the meaning of modules and objects, and lookup for documentation. **But**, in the description above, **according to documentation** is important statement. Because according to introspection, method definitions are spread differently: ```ruby puts "Public" Object.new .then { |o| o.methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } puts puts "Private:" Object.new .then { |o| o.private_methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } ``` Output: ``` Public Kernel: !~, <=>, ===, class, clone, define_singleton_method, display, dup, enum_for, eql?, extend, freeze, frozen?, hash, inspect, instance_of?, instance_variable_defined?, instance_variable_get, instance_variable_set, instance_variables, is_a?, itself, kind_of?, method, methods, nil?, object_id, private_methods, protected_methods, public_method, public_methods, public_send, remove_instance_variable, respond_to?, send, singleton_class, singleton_method, singleton_methods, tap, then, to_enum, to_s, yield_self BasicObject: !, !=, ==, __id__, __send__, equal?, instance_eval, instance_exec Private: Kernel: Array, Complex, Float, Hash, Integer, Rational, String, __callee__, __dir__, __method__, `, abort, at_exit, autoload, autoload?, binding, block_given?, caller, caller_locations, catch, eval, exec, exit, exit!, fail, fork, format, gem, gem_original_require, gets, global_variables, initialize_clone, initialize_copy, initialize_dup, iterator?, lambda, load, local_variables, loop, open, p, pp, print, printf, proc, putc, puts, raise, rand, readline, readlines, require, require_relative, respond_to_missing?, select, set_trace_func, sleep, spawn, sprintf, srand, syscall, system, test, throw, trace_var, trap, untrace_var, warn BasicObject: initialize, method_missing, singleton_method_added, singleton_method_removed, singleton_method_undefined ``` E.g., internally, `Object` doesn't have _any_ method defined, and is just a `BasicObject` with `Kernel` included. So, there are three questions/proposals: 1. Does this disposition has some internal sense, or it is more of a historical thing? 2. Can it be changed so that public methods belonged to `Object` instead of `Kernel`? 3. If the answer to (2) is "no", can at least docs for `clone`, `tap` and `then` be adjusted to follow other public methods in pretending they are `Object`'s features? -- https://bugs.ruby-lang.org/

Issue #19300 has been updated by Eregon (Benoit Daloze). To add on that, I have seen many many Rubyists confused due to RDoc showing Kernel methods on Object.html. They thought all those methods are defined on Object and not on Kernel, but it's all a lie and confusion by RDoc. So I guess the original intention was to simplify for beginners, but actually I think it hurts more than it helps. Better fix it now than never. ---------------------------------------- Feature #19300: Move public objects from Kernel to Object https://bugs.ruby-lang.org/issues/19300#change-100967 * Author: zverok (Victor Shepelev) * Status: Third Party's Issue * Priority: Normal ---------------------------------------- In my understanding, `Kernel` is a container for methods that are perceived as "global", and are available inside every objects as its private methods, like `puts` ```ruby class A def foo = puts "foo" end a = A.new a.foo # prints "foo" a.puts 'bar' # private method `puts' called for #<A:0x00007f39a683db28> (NoMethodError) ``` There are, though, exactly three (if I am not missing something) methods that, **according to documentation**, break this intuition and belong to [Kernel](https://docs.ruby-lang.org/en/master/Kernel.html): * `clone` * `tap` * `then` All those methods are public method for a receiver, and they mostly make sense with an explicit receiver. The most confusing of them is `#clone`, which is close cousin of `#dup`, but it is [Kernel#clone](https://docs.ruby-lang.org/en/master/Kernel.html#method-i-clone) and [Object#dup](https://docs.ruby-lang.org/en/master/Object.html#method-i-dup). This state of things is mostly harmless in practical code, but very inconvenient for teaching, reasoning about the meaning of modules and objects, and lookup for documentation. **But**, in the description above, **according to documentation** is important statement. Because according to introspection, method definitions are spread differently: ```ruby puts "Public" Object.new .then { |o| o.methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } puts puts "Private:" Object.new .then { |o| o.private_methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } ``` Output: ``` Public Kernel: !~, <=>, ===, class, clone, define_singleton_method, display, dup, enum_for, eql?, extend, freeze, frozen?, hash, inspect, instance_of?, instance_variable_defined?, instance_variable_get, instance_variable_set, instance_variables, is_a?, itself, kind_of?, method, methods, nil?, object_id, private_methods, protected_methods, public_method, public_methods, public_send, remove_instance_variable, respond_to?, send, singleton_class, singleton_method, singleton_methods, tap, then, to_enum, to_s, yield_self BasicObject: !, !=, ==, __id__, __send__, equal?, instance_eval, instance_exec Private: Kernel: Array, Complex, Float, Hash, Integer, Rational, String, __callee__, __dir__, __method__, `, abort, at_exit, autoload, autoload?, binding, block_given?, caller, caller_locations, catch, eval, exec, exit, exit!, fail, fork, format, gem, gem_original_require, gets, global_variables, initialize_clone, initialize_copy, initialize_dup, iterator?, lambda, load, local_variables, loop, open, p, pp, print, printf, proc, putc, puts, raise, rand, readline, readlines, require, require_relative, respond_to_missing?, select, set_trace_func, sleep, spawn, sprintf, srand, syscall, system, test, throw, trace_var, trap, untrace_var, warn BasicObject: initialize, method_missing, singleton_method_added, singleton_method_removed, singleton_method_undefined ``` E.g., internally, `Object` doesn't have _any_ method defined, and is just a `BasicObject` with `Kernel` included. So, there are three questions/proposals: 1. Does this disposition has some internal sense, or it is more of a historical thing? 2. Can it be changed so that public methods belonged to `Object` instead of `Kernel`? 3. If the answer to (2) is "no", can at least docs for `clone`, `tap` and `then` be adjusted to follow other public methods in pretending they are `Object`'s features? -- https://bugs.ruby-lang.org/

Issue #19300 has been updated by zverok (Victor Shepelev). @nobu OK, I discovered the same while answering to @Eregon. Do you believe the problem should be handled by 1. **adding** more "edge cases" to RDoc (supporting `kernel.rb`)? 2. **removing** edge cases from RDoc (all methods that pretended to belong to `Object` go to `Kernel`)? 3. somehow adjusting docs structure in `kernel.rb` to "move" them to `Object` (I tried the simple `Document-method: Object#clone` trick, but it didn't work in Ruby sources)?.. 4. adjusting the code structure to better suit docs? (E.g. introducing _at least_ `object.rb` and moving 5 mentioned methods there, and proceeding this way while probably extracting the rest in the future)? TBH, I am most in favor of 4, as it seems to align the reality with the mental model that docs seem to _always_ impose on the language users. But it is the most severe decision of the mentioned ones.
Hence, it's 100% a bug of RDoc, it was a mistake to show Kernel methods on Object.html, I think now it's obviously clear. Let's fix it.
Please, let's not. The mental model of "you look in `Kernel` to see 'global' methods available everywhere without a receiver, you look in `Object` to see generic methods every object has" is of tremendous significance, even if it doesn't correspond to reality. Otherwise, it is incredibly confusing to see them in the same module: like, it will tell you, "every object has `puts` and `class`", because that's actually **a lie** in the meaning of usage. If it is the only choice, I would rather add more hacks to RDoc to continue supporting the illusion. **The alternative is to (maybe gradually) shift the reality towards the useful illusion and separate "private 'global' methods" (of Kernel) and "public methods every object has" (of Object).**
Better fix it now than never.
I agree with the intention, but not with the method :) ---------------------------------------- Feature #19300: Move public objects from Kernel to Object https://bugs.ruby-lang.org/issues/19300#change-100968 * Author: zverok (Victor Shepelev) * Status: Third Party's Issue * Priority: Normal ---------------------------------------- In my understanding, `Kernel` is a container for methods that are perceived as "global", and are available inside every objects as its private methods, like `puts` ```ruby class A def foo = puts "foo" end a = A.new a.foo # prints "foo" a.puts 'bar' # private method `puts' called for #<A:0x00007f39a683db28> (NoMethodError) ``` There are, though, exactly three (if I am not missing something) methods that, **according to documentation**, break this intuition and belong to [Kernel](https://docs.ruby-lang.org/en/master/Kernel.html): * `clone` * `tap` * `then` All those methods are public method for a receiver, and they mostly make sense with an explicit receiver. The most confusing of them is `#clone`, which is close cousin of `#dup`, but it is [Kernel#clone](https://docs.ruby-lang.org/en/master/Kernel.html#method-i-clone) and [Object#dup](https://docs.ruby-lang.org/en/master/Object.html#method-i-dup). This state of things is mostly harmless in practical code, but very inconvenient for teaching, reasoning about the meaning of modules and objects, and lookup for documentation. **But**, in the description above, **according to documentation** is important statement. Because according to introspection, method definitions are spread differently: ```ruby puts "Public" Object.new .then { |o| o.methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } puts puts "Private:" Object.new .then { |o| o.private_methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } ``` Output: ``` Public Kernel: !~, <=>, ===, class, clone, define_singleton_method, display, dup, enum_for, eql?, extend, freeze, frozen?, hash, inspect, instance_of?, instance_variable_defined?, instance_variable_get, instance_variable_set, instance_variables, is_a?, itself, kind_of?, method, methods, nil?, object_id, private_methods, protected_methods, public_method, public_methods, public_send, remove_instance_variable, respond_to?, send, singleton_class, singleton_method, singleton_methods, tap, then, to_enum, to_s, yield_self BasicObject: !, !=, ==, __id__, __send__, equal?, instance_eval, instance_exec Private: Kernel: Array, Complex, Float, Hash, Integer, Rational, String, __callee__, __dir__, __method__, `, abort, at_exit, autoload, autoload?, binding, block_given?, caller, caller_locations, catch, eval, exec, exit, exit!, fail, fork, format, gem, gem_original_require, gets, global_variables, initialize_clone, initialize_copy, initialize_dup, iterator?, lambda, load, local_variables, loop, open, p, pp, print, printf, proc, putc, puts, raise, rand, readline, readlines, require, require_relative, respond_to_missing?, select, set_trace_func, sleep, spawn, sprintf, srand, syscall, system, test, throw, trace_var, trap, untrace_var, warn BasicObject: initialize, method_missing, singleton_method_added, singleton_method_removed, singleton_method_undefined ``` E.g., internally, `Object` doesn't have _any_ method defined, and is just a `BasicObject` with `Kernel` included. So, there are three questions/proposals: 1. Does this disposition has some internal sense, or it is more of a historical thing? 2. Can it be changed so that public methods belonged to `Object` instead of `Kernel`? 3. If the answer to (2) is "no", can at least docs for `clone`, `tap` and `then` be adjusted to follow other public methods in pretending they are `Object`'s features? -- https://bugs.ruby-lang.org/

Issue #19300 has been updated by Eregon (Benoit Daloze). The title is pretty confusing, but is a bit clearer with those questions: zverok (Victor Shepelev) wrote:
So, there are three questions/proposals: 1. Does this disposition has some internal sense, or it is more of a historical thing?
I believe it's all intended. So `Object` is not special and it's possible and meaningful to `include Kernel` (e.g., in some BasicObject subclass) Private methods of Kernel are meant to be receiver-less methods, hence they are on Kernel for "everywhere" and not on Object which would mean the receiver matters.
2. Can it be changed so that public methods belonged to `Object` instead of `Kernel`?
No, it would break `Kernel.rand` for instance.
3. If the answer to (2) is "no", can at least docs for `clone`, `tap` and `then` be adjusted to follow other public methods in pretending they are `Object`'s features?
I think it's time to fix this RDoc bug. But anyway, something to change in RDoc, not in Ruby. ---------------------------------------- Feature #19300: Move public objects from Kernel to Object https://bugs.ruby-lang.org/issues/19300#change-100969 * Author: zverok (Victor Shepelev) * Status: Third Party's Issue * Priority: Normal ---------------------------------------- In my understanding, `Kernel` is a container for methods that are perceived as "global", and are available inside every objects as its private methods, like `puts` ```ruby class A def foo = puts "foo" end a = A.new a.foo # prints "foo" a.puts 'bar' # private method `puts' called for #<A:0x00007f39a683db28> (NoMethodError) ``` There are, though, exactly three (if I am not missing something) methods that, **according to documentation**, break this intuition and belong to [Kernel](https://docs.ruby-lang.org/en/master/Kernel.html): * `clone` * `tap` * `then` All those methods are public method for a receiver, and they mostly make sense with an explicit receiver. The most confusing of them is `#clone`, which is close cousin of `#dup`, but it is [Kernel#clone](https://docs.ruby-lang.org/en/master/Kernel.html#method-i-clone) and [Object#dup](https://docs.ruby-lang.org/en/master/Object.html#method-i-dup). This state of things is mostly harmless in practical code, but very inconvenient for teaching, reasoning about the meaning of modules and objects, and lookup for documentation. **But**, in the description above, **according to documentation** is important statement. Because according to introspection, method definitions are spread differently: ```ruby puts "Public" Object.new .then { |o| o.methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } puts puts "Private:" Object.new .then { |o| o.private_methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } ``` Output: ``` Public Kernel: !~, <=>, ===, class, clone, define_singleton_method, display, dup, enum_for, eql?, extend, freeze, frozen?, hash, inspect, instance_of?, instance_variable_defined?, instance_variable_get, instance_variable_set, instance_variables, is_a?, itself, kind_of?, method, methods, nil?, object_id, private_methods, protected_methods, public_method, public_methods, public_send, remove_instance_variable, respond_to?, send, singleton_class, singleton_method, singleton_methods, tap, then, to_enum, to_s, yield_self BasicObject: !, !=, ==, __id__, __send__, equal?, instance_eval, instance_exec Private: Kernel: Array, Complex, Float, Hash, Integer, Rational, String, __callee__, __dir__, __method__, `, abort, at_exit, autoload, autoload?, binding, block_given?, caller, caller_locations, catch, eval, exec, exit, exit!, fail, fork, format, gem, gem_original_require, gets, global_variables, initialize_clone, initialize_copy, initialize_dup, iterator?, lambda, load, local_variables, loop, open, p, pp, print, printf, proc, putc, puts, raise, rand, readline, readlines, require, require_relative, respond_to_missing?, select, set_trace_func, sleep, spawn, sprintf, srand, syscall, system, test, throw, trace_var, trap, untrace_var, warn BasicObject: initialize, method_missing, singleton_method_added, singleton_method_removed, singleton_method_undefined ``` E.g., internally, `Object` doesn't have _any_ method defined, and is just a `BasicObject` with `Kernel` included. So, there are three questions/proposals: 1. Does this disposition has some internal sense, or it is more of a historical thing? 2. Can it be changed so that public methods belonged to `Object` instead of `Kernel`? 3. If the answer to (2) is "no", can at least docs for `clone`, `tap` and `then` be adjusted to follow other public methods in pretending they are `Object`'s features? -- https://bugs.ruby-lang.org/

Issue #19300 has been updated by zverok (Victor Shepelev). Status changed from Third Party's Issue to Rejected
The title is pretty confusing, but is a bit clearer with those questions:
Yeah, I actually started to write ticket thinking it is a small docs problem (as many of us, I frequently forget they all belong to Kernel), but then while trying to provide the full perspective, clarified what bothers me. I actually think I'll restart it from scratch in dev-meeting-discussion-ready form :) ---------------------------------------- Feature #19300: Move public methods from Kernel to Object https://bugs.ruby-lang.org/issues/19300#change-100971 * Author: zverok (Victor Shepelev) * Status: Rejected * Priority: Normal ---------------------------------------- In my understanding, `Kernel` is a container for methods that are perceived as "global", and are available inside every objects as its private methods, like `puts` ```ruby class A def foo = puts "foo" end a = A.new a.foo # prints "foo" a.puts 'bar' # private method `puts' called for #<A:0x00007f39a683db28> (NoMethodError) ``` There are, though, exactly three (if I am not missing something) methods that, **according to documentation**, break this intuition and belong to [Kernel](https://docs.ruby-lang.org/en/master/Kernel.html): * `clone` * `tap` * `then` All those methods are public method for a receiver, and they mostly make sense with an explicit receiver. The most confusing of them is `#clone`, which is close cousin of `#dup`, but it is [Kernel#clone](https://docs.ruby-lang.org/en/master/Kernel.html#method-i-clone) and [Object#dup](https://docs.ruby-lang.org/en/master/Object.html#method-i-dup). This state of things is mostly harmless in practical code, but very inconvenient for teaching, reasoning about the meaning of modules and objects, and lookup for documentation. **But**, in the description above, **according to documentation** is important statement. Because according to introspection, method definitions are spread differently: ```ruby puts "Public" Object.new .then { |o| o.methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } puts puts "Private:" Object.new .then { |o| o.private_methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } ``` Output: ``` Public Kernel: !~, <=>, ===, class, clone, define_singleton_method, display, dup, enum_for, eql?, extend, freeze, frozen?, hash, inspect, instance_of?, instance_variable_defined?, instance_variable_get, instance_variable_set, instance_variables, is_a?, itself, kind_of?, method, methods, nil?, object_id, private_methods, protected_methods, public_method, public_methods, public_send, remove_instance_variable, respond_to?, send, singleton_class, singleton_method, singleton_methods, tap, then, to_enum, to_s, yield_self BasicObject: !, !=, ==, __id__, __send__, equal?, instance_eval, instance_exec Private: Kernel: Array, Complex, Float, Hash, Integer, Rational, String, __callee__, __dir__, __method__, `, abort, at_exit, autoload, autoload?, binding, block_given?, caller, caller_locations, catch, eval, exec, exit, exit!, fail, fork, format, gem, gem_original_require, gets, global_variables, initialize_clone, initialize_copy, initialize_dup, iterator?, lambda, load, local_variables, loop, open, p, pp, print, printf, proc, putc, puts, raise, rand, readline, readlines, require, require_relative, respond_to_missing?, select, set_trace_func, sleep, spawn, sprintf, srand, syscall, system, test, throw, trace_var, trap, untrace_var, warn BasicObject: initialize, method_missing, singleton_method_added, singleton_method_removed, singleton_method_undefined ``` E.g., internally, `Object` doesn't have _any_ method defined, and is just a `BasicObject` with `Kernel` included. So, there are three questions/proposals: 1. Does this disposition has some internal sense, or it is more of a historical thing? 2. Can it be changed so that public methods belonged to `Object` instead of `Kernel`? 3. If the answer to (2) is "no", can at least docs for `clone`, `tap` and `then` be adjusted to follow other public methods in pretending they are `Object`'s features? -- https://bugs.ruby-lang.org/

Issue #19300 has been updated by Eregon (Benoit Daloze). zverok (Victor Shepelev) wrote in #note-7:
The mental model of "you look in `Kernel` to see 'global' methods available everywhere without a receiver, you look in `Object` to see generic methods every object has" is of tremendous significance, even if it doesn't correspond to reality.
I agree separating those somehow makes sense. Although it could be done in the same page and just list all public and all private methods separately, isn't it? The fact visibility is not shown properly at https://docs.ruby-lang.org/en/master/Kernel.html is part of the issue. Like `Public Instance Methods` - `#Array`, that's wrong. When I look at https://docs.ruby-lang.org/en/master/Kernel.html https://docs.ruby-lang.org/en/master/Object.html I see a tremendous mess I would never be able to make sense of. For instance the Kernel.html page has both `frozen?` and `require` in the same section, that's confusing, and I guess another case like you mentioned above. I can see your POV now. So I'm against more hacks in RDoc to fix this inconsistency in the short term. I do think pretending methods are in Object instead of Kernel hurts than it helps, but indeed, there also needs to be a clear split between public and private (with receiver/receives-less) instance methods of Kernel.
Otherwise, it is incredibly confusing to see them in the same module: like, it will tell you, "every object has `puts` and `class`", because that's actually **a lie** in the meaning of usage.
`puts` as private, `class` as public, that tells you whether you should use a receiver or not. ---------------------------------------- Feature #19300: Move public methods from Kernel to Object https://bugs.ruby-lang.org/issues/19300#change-100972 * Author: zverok (Victor Shepelev) * Status: Rejected * Priority: Normal ---------------------------------------- In my understanding, `Kernel` is a container for methods that are perceived as "global", and are available inside every objects as its private methods, like `puts` ```ruby class A def foo = puts "foo" end a = A.new a.foo # prints "foo" a.puts 'bar' # private method `puts' called for #<A:0x00007f39a683db28> (NoMethodError) ``` There are, though, exactly three (if I am not missing something) methods that, **according to documentation**, break this intuition and belong to [Kernel](https://docs.ruby-lang.org/en/master/Kernel.html): * `clone` * `tap` * `then` All those methods are public method for a receiver, and they mostly make sense with an explicit receiver. The most confusing of them is `#clone`, which is close cousin of `#dup`, but it is [Kernel#clone](https://docs.ruby-lang.org/en/master/Kernel.html#method-i-clone) and [Object#dup](https://docs.ruby-lang.org/en/master/Object.html#method-i-dup). This state of things is mostly harmless in practical code, but very inconvenient for teaching, reasoning about the meaning of modules and objects, and lookup for documentation. **But**, in the description above, **according to documentation** is important statement. Because according to introspection, method definitions are spread differently: ```ruby puts "Public" Object.new .then { |o| o.methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } puts puts "Private:" Object.new .then { |o| o.private_methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } ``` Output: ``` Public Kernel: !~, <=>, ===, class, clone, define_singleton_method, display, dup, enum_for, eql?, extend, freeze, frozen?, hash, inspect, instance_of?, instance_variable_defined?, instance_variable_get, instance_variable_set, instance_variables, is_a?, itself, kind_of?, method, methods, nil?, object_id, private_methods, protected_methods, public_method, public_methods, public_send, remove_instance_variable, respond_to?, send, singleton_class, singleton_method, singleton_methods, tap, then, to_enum, to_s, yield_self BasicObject: !, !=, ==, __id__, __send__, equal?, instance_eval, instance_exec Private: Kernel: Array, Complex, Float, Hash, Integer, Rational, String, __callee__, __dir__, __method__, `, abort, at_exit, autoload, autoload?, binding, block_given?, caller, caller_locations, catch, eval, exec, exit, exit!, fail, fork, format, gem, gem_original_require, gets, global_variables, initialize_clone, initialize_copy, initialize_dup, iterator?, lambda, load, local_variables, loop, open, p, pp, print, printf, proc, putc, puts, raise, rand, readline, readlines, require, require_relative, respond_to_missing?, select, set_trace_func, sleep, spawn, sprintf, srand, syscall, system, test, throw, trace_var, trap, untrace_var, warn BasicObject: initialize, method_missing, singleton_method_added, singleton_method_removed, singleton_method_undefined ``` E.g., internally, `Object` doesn't have _any_ method defined, and is just a `BasicObject` with `Kernel` included. So, there are three questions/proposals: 1. Does this disposition has some internal sense, or it is more of a historical thing? 2. Can it be changed so that public methods belonged to `Object` instead of `Kernel`? 3. If the answer to (2) is "no", can at least docs for `clone`, `tap` and `then` be adjusted to follow other public methods in pretending they are `Object`'s features? -- https://bugs.ruby-lang.org/

Issue #19300 has been updated by Eregon (Benoit Daloze).
I actually think I'll restart it from scratch in dev-meeting-discussion-ready form :)
IMHO this is purely an issue of RDoc, and so best to discuss it there or make a PR there. Ruby methods will not have a different module/class to workaround this RDoc issue, I think that much is clear. I'm pretty sure it's fine to add some special RDoc comment to `kernel.rb` so RDoc can recognize it (or maybe just use the filename or some command-line arg?). IMHO there should not be an `object.rb` (since no methods are defined on `Object`), that would again leak some RDoc issue into Ruby. ---------------------------------------- Feature #19300: Move public methods from Kernel to Object https://bugs.ruby-lang.org/issues/19300#change-100973 * Author: zverok (Victor Shepelev) * Status: Rejected * Priority: Normal ---------------------------------------- In my understanding, `Kernel` is a container for methods that are perceived as "global", and are available inside every objects as its private methods, like `puts` ```ruby class A def foo = puts "foo" end a = A.new a.foo # prints "foo" a.puts 'bar' # private method `puts' called for #<A:0x00007f39a683db28> (NoMethodError) ``` There are, though, exactly three (if I am not missing something) methods that, **according to documentation**, break this intuition and belong to [Kernel](https://docs.ruby-lang.org/en/master/Kernel.html): * `clone` * `tap` * `then` All those methods are public method for a receiver, and they mostly make sense with an explicit receiver. The most confusing of them is `#clone`, which is close cousin of `#dup`, but it is [Kernel#clone](https://docs.ruby-lang.org/en/master/Kernel.html#method-i-clone) and [Object#dup](https://docs.ruby-lang.org/en/master/Object.html#method-i-dup). This state of things is mostly harmless in practical code, but very inconvenient for teaching, reasoning about the meaning of modules and objects, and lookup for documentation. **But**, in the description above, **according to documentation** is important statement. Because according to introspection, method definitions are spread differently: ```ruby puts "Public" Object.new .then { |o| o.methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } puts puts "Private:" Object.new .then { |o| o.private_methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } ``` Output: ``` Public Kernel: !~, <=>, ===, class, clone, define_singleton_method, display, dup, enum_for, eql?, extend, freeze, frozen?, hash, inspect, instance_of?, instance_variable_defined?, instance_variable_get, instance_variable_set, instance_variables, is_a?, itself, kind_of?, method, methods, nil?, object_id, private_methods, protected_methods, public_method, public_methods, public_send, remove_instance_variable, respond_to?, send, singleton_class, singleton_method, singleton_methods, tap, then, to_enum, to_s, yield_self BasicObject: !, !=, ==, __id__, __send__, equal?, instance_eval, instance_exec Private: Kernel: Array, Complex, Float, Hash, Integer, Rational, String, __callee__, __dir__, __method__, `, abort, at_exit, autoload, autoload?, binding, block_given?, caller, caller_locations, catch, eval, exec, exit, exit!, fail, fork, format, gem, gem_original_require, gets, global_variables, initialize_clone, initialize_copy, initialize_dup, iterator?, lambda, load, local_variables, loop, open, p, pp, print, printf, proc, putc, puts, raise, rand, readline, readlines, require, require_relative, respond_to_missing?, select, set_trace_func, sleep, spawn, sprintf, srand, syscall, system, test, throw, trace_var, trap, untrace_var, warn BasicObject: initialize, method_missing, singleton_method_added, singleton_method_removed, singleton_method_undefined ``` E.g., internally, `Object` doesn't have _any_ method defined, and is just a `BasicObject` with `Kernel` included. So, there are three questions/proposals: 1. Does this disposition has some internal sense, or it is more of a historical thing? 2. Can it be changed so that public methods belonged to `Object` instead of `Kernel`? 3. If the answer to (2) is "no", can at least docs for `clone`, `tap` and `then` be adjusted to follow other public methods in pretending they are `Object`'s features? -- https://bugs.ruby-lang.org/

Issue #19300 has been updated by zverok (Victor Shepelev).
IMHO this is purely an issue of RDoc, and so best to discuss it there or make a PR there.
I don't think so. The question is "how the language should be documented", not "how the documentation tool (RDoc) should work". The outcome of the discussion is of community significance (how new and growing Rubyists would understand some concepts), not of decorative significance (how some thing or other should render). I might be the only person who considers it all that important, though. ---------------------------------------- Feature #19300: Move public methods from Kernel to Object https://bugs.ruby-lang.org/issues/19300#change-100974 * Author: zverok (Victor Shepelev) * Status: Rejected * Priority: Normal ---------------------------------------- In my understanding, `Kernel` is a container for methods that are perceived as "global", and are available inside every objects as its private methods, like `puts` ```ruby class A def foo = puts "foo" end a = A.new a.foo # prints "foo" a.puts 'bar' # private method `puts' called for #<A:0x00007f39a683db28> (NoMethodError) ``` There are, though, exactly three (if I am not missing something) methods that, **according to documentation**, break this intuition and belong to [Kernel](https://docs.ruby-lang.org/en/master/Kernel.html): * `clone` * `tap` * `then` All those methods are public method for a receiver, and they mostly make sense with an explicit receiver. The most confusing of them is `#clone`, which is close cousin of `#dup`, but it is [Kernel#clone](https://docs.ruby-lang.org/en/master/Kernel.html#method-i-clone) and [Object#dup](https://docs.ruby-lang.org/en/master/Object.html#method-i-dup). This state of things is mostly harmless in practical code, but very inconvenient for teaching, reasoning about the meaning of modules and objects, and lookup for documentation. **But**, in the description above, **according to documentation** is important statement. Because according to introspection, method definitions are spread differently: ```ruby puts "Public" Object.new .then { |o| o.methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } puts puts "Private:" Object.new .then { |o| o.private_methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } ``` Output: ``` Public Kernel: !~, <=>, ===, class, clone, define_singleton_method, display, dup, enum_for, eql?, extend, freeze, frozen?, hash, inspect, instance_of?, instance_variable_defined?, instance_variable_get, instance_variable_set, instance_variables, is_a?, itself, kind_of?, method, methods, nil?, object_id, private_methods, protected_methods, public_method, public_methods, public_send, remove_instance_variable, respond_to?, send, singleton_class, singleton_method, singleton_methods, tap, then, to_enum, to_s, yield_self BasicObject: !, !=, ==, __id__, __send__, equal?, instance_eval, instance_exec Private: Kernel: Array, Complex, Float, Hash, Integer, Rational, String, __callee__, __dir__, __method__, `, abort, at_exit, autoload, autoload?, binding, block_given?, caller, caller_locations, catch, eval, exec, exit, exit!, fail, fork, format, gem, gem_original_require, gets, global_variables, initialize_clone, initialize_copy, initialize_dup, iterator?, lambda, load, local_variables, loop, open, p, pp, print, printf, proc, putc, puts, raise, rand, readline, readlines, require, require_relative, respond_to_missing?, select, set_trace_func, sleep, spawn, sprintf, srand, syscall, system, test, throw, trace_var, trap, untrace_var, warn BasicObject: initialize, method_missing, singleton_method_added, singleton_method_removed, singleton_method_undefined ``` E.g., internally, `Object` doesn't have _any_ method defined, and is just a `BasicObject` with `Kernel` included. So, there are three questions/proposals: 1. Does this disposition has some internal sense, or it is more of a historical thing? 2. Can it be changed so that public methods belonged to `Object` instead of `Kernel`? 3. If the answer to (2) is "no", can at least docs for `clone`, `tap` and `then` be adjusted to follow other public methods in pretending they are `Object`'s features? -- https://bugs.ruby-lang.org/

Issue #19300 has been updated by mame (Yusuke Endoh). Useless history talk. I once asked matz why Kernel exists. If I remember correctly, matz said the following. * In the beginning, there was a usage distinction of putting global function-like methods (exit, eval, etc.) in Kernel and method-like methods (clone, kind_of?, etc.) in Object. * However, this distinction was cumbersome to manage and had little advantage, so gradually everything was placed in Kernel. In ruby 0.49 (1994/07/18), the earliest code available, we can see this distinction. ```` rb_define_func(C_Kernel, "exit", Fexit, -2); rb_define_func(C_Kernel, "eval", Feval, 1); ... rb_define_method(C_Object, "is_kind_of", obj_is_kind_of, 1); rb_define_method(C_Object, "clone", Fobj_clone, 0); ```` However, there was already some confusion; `Kernel#class` and `Kernel#hash` were defined in Kernel. (Incidentally, a little interestingly, Kernel was a class, not a module, at that time.) After that, it looks like matz did some design trial and error; a new class called `Builtin` was introduced between Kernel and Object, and every global function-like methods were moved to Builtin. However this was eventually reverted. Then, everything was gradually moved to Kernel, as matz said. As of ruby 0.95 (1995/12/21), `Object#clone` moved to Kernel, and as of ruby 1.0-961125, `Object#is_kind_of` moved to Kernel (as `Kernel#kind_of?`). In ruby 1.0-971002, `Object#inspect`, which was maybe the last method defined directly under Object, was moved to Kernel. I don't know why rdoc introduced the trick to replace `rb_mKernel` with `rb_cObject`, but the author (Dave Thomas) maybe remembered how Kernel used to be. ---------------------------------------- Feature #19300: Move public methods from Kernel to Object https://bugs.ruby-lang.org/issues/19300#change-101067 * Author: zverok (Victor Shepelev) * Status: Rejected * Priority: Normal ---------------------------------------- In my understanding, `Kernel` is a container for methods that are perceived as "global", and are available inside every objects as its private methods, like `puts` ```ruby class A def foo = puts "foo" end a = A.new a.foo # prints "foo" a.puts 'bar' # private method `puts' called for #<A:0x00007f39a683db28> (NoMethodError) ``` There are, though, exactly three (if I am not missing something) methods that, **according to documentation**, break this intuition and belong to [Kernel](https://docs.ruby-lang.org/en/master/Kernel.html): * `clone` * `tap` * `then` All those methods are public method for a receiver, and they mostly make sense with an explicit receiver. The most confusing of them is `#clone`, which is close cousin of `#dup`, but it is [Kernel#clone](https://docs.ruby-lang.org/en/master/Kernel.html#method-i-clone) and [Object#dup](https://docs.ruby-lang.org/en/master/Object.html#method-i-dup). This state of things is mostly harmless in practical code, but very inconvenient for teaching, reasoning about the meaning of modules and objects, and lookup for documentation. **But**, in the description above, **according to documentation** is important statement. Because according to introspection, method definitions are spread differently: ```ruby puts "Public" Object.new .then { |o| o.methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } puts puts "Private:" Object.new .then { |o| o.private_methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } ``` Output: ``` Public Kernel: !~, <=>, ===, class, clone, define_singleton_method, display, dup, enum_for, eql?, extend, freeze, frozen?, hash, inspect, instance_of?, instance_variable_defined?, instance_variable_get, instance_variable_set, instance_variables, is_a?, itself, kind_of?, method, methods, nil?, object_id, private_methods, protected_methods, public_method, public_methods, public_send, remove_instance_variable, respond_to?, send, singleton_class, singleton_method, singleton_methods, tap, then, to_enum, to_s, yield_self BasicObject: !, !=, ==, __id__, __send__, equal?, instance_eval, instance_exec Private: Kernel: Array, Complex, Float, Hash, Integer, Rational, String, __callee__, __dir__, __method__, `, abort, at_exit, autoload, autoload?, binding, block_given?, caller, caller_locations, catch, eval, exec, exit, exit!, fail, fork, format, gem, gem_original_require, gets, global_variables, initialize_clone, initialize_copy, initialize_dup, iterator?, lambda, load, local_variables, loop, open, p, pp, print, printf, proc, putc, puts, raise, rand, readline, readlines, require, require_relative, respond_to_missing?, select, set_trace_func, sleep, spawn, sprintf, srand, syscall, system, test, throw, trace_var, trap, untrace_var, warn BasicObject: initialize, method_missing, singleton_method_added, singleton_method_removed, singleton_method_undefined ``` E.g., internally, `Object` doesn't have _any_ method defined, and is just a `BasicObject` with `Kernel` included. So, there are three questions/proposals: 1. Does this disposition has some internal sense, or it is more of a historical thing? 2. Can it be changed so that public methods belonged to `Object` instead of `Kernel`? 3. If the answer to (2) is "no", can at least docs for `clone`, `tap` and `then` be adjusted to follow other public methods in pretending they are `Object`'s features? -- https://bugs.ruby-lang.org/

Issue #19300 has been updated by zverok (Victor Shepelev). Thanks, @mame, it is pretty educative and exactly the answer I was looking for in my first ("historical") question! ---------------------------------------- Feature #19300: Move public methods from Kernel to Object https://bugs.ruby-lang.org/issues/19300#change-101139 * Author: zverok (Victor Shepelev) * Status: Rejected * Priority: Normal ---------------------------------------- In my understanding, `Kernel` is a container for methods that are perceived as "global", and are available inside every objects as its private methods, like `puts` ```ruby class A def foo = puts "foo" end a = A.new a.foo # prints "foo" a.puts 'bar' # private method `puts' called for #<A:0x00007f39a683db28> (NoMethodError) ``` There are, though, exactly three (if I am not missing something) methods that, **according to documentation**, break this intuition and belong to [Kernel](https://docs.ruby-lang.org/en/master/Kernel.html): * `clone` * `tap` * `then` All those methods are public method for a receiver, and they mostly make sense with an explicit receiver. The most confusing of them is `#clone`, which is close cousin of `#dup`, but it is [Kernel#clone](https://docs.ruby-lang.org/en/master/Kernel.html#method-i-clone) and [Object#dup](https://docs.ruby-lang.org/en/master/Object.html#method-i-dup). This state of things is mostly harmless in practical code, but very inconvenient for teaching, reasoning about the meaning of modules and objects, and lookup for documentation. **But**, in the description above, **according to documentation** is important statement. Because according to introspection, method definitions are spread differently: ```ruby puts "Public" Object.new .then { |o| o.methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } puts puts "Private:" Object.new .then { |o| o.private_methods.group_by { o.method(_1).owner } } .each { puts "#{_1}: #{_2.sort.join(', ')}" } ``` Output: ``` Public Kernel: !~, <=>, ===, class, clone, define_singleton_method, display, dup, enum_for, eql?, extend, freeze, frozen?, hash, inspect, instance_of?, instance_variable_defined?, instance_variable_get, instance_variable_set, instance_variables, is_a?, itself, kind_of?, method, methods, nil?, object_id, private_methods, protected_methods, public_method, public_methods, public_send, remove_instance_variable, respond_to?, send, singleton_class, singleton_method, singleton_methods, tap, then, to_enum, to_s, yield_self BasicObject: !, !=, ==, __id__, __send__, equal?, instance_eval, instance_exec Private: Kernel: Array, Complex, Float, Hash, Integer, Rational, String, __callee__, __dir__, __method__, `, abort, at_exit, autoload, autoload?, binding, block_given?, caller, caller_locations, catch, eval, exec, exit, exit!, fail, fork, format, gem, gem_original_require, gets, global_variables, initialize_clone, initialize_copy, initialize_dup, iterator?, lambda, load, local_variables, loop, open, p, pp, print, printf, proc, putc, puts, raise, rand, readline, readlines, require, require_relative, respond_to_missing?, select, set_trace_func, sleep, spawn, sprintf, srand, syscall, system, test, throw, trace_var, trap, untrace_var, warn BasicObject: initialize, method_missing, singleton_method_added, singleton_method_removed, singleton_method_undefined ``` E.g., internally, `Object` doesn't have _any_ method defined, and is just a `BasicObject` with `Kernel` included. So, there are three questions/proposals: 1. Does this disposition has some internal sense, or it is more of a historical thing? 2. Can it be changed so that public methods belonged to `Object` instead of `Kernel`? 3. If the answer to (2) is "no", can at least docs for `clone`, `tap` and `then` be adjusted to follow other public methods in pretending they are `Object`'s features? -- https://bugs.ruby-lang.org/
participants (5)
-
Eregon (Benoit Daloze)
-
hmdne (hmdne -)
-
mame (Yusuke Endoh)
-
nobu (Nobuyoshi Nakada)
-
zverok (Victor Shepelev)