From: "Eregon (Benoit Daloze) via ruby-core" <ruby-core@...> Date: 2023-01-03T13:28:39+00:00 Subject: [ruby-core:111600] [Ruby master Feature#19300] Move public objects from Kernel to Object 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/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/