Project

General

Profile

Actions

Feature #19300

closed

Move public methods from Kernel to Object

Added by zverok (Victor Shepelev) over 1 year ago. Updated over 1 year ago.

Status:
Rejected
Assignee:
-
Target version:
-
[ruby-core:111579]

Description

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

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:

  • 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 and Object#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:

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?
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0