From: "shugo (Shugo Maeda) via ruby-core" Date: 2026-09-10T07:46:47+00:00 Subject: [ruby-core:126638] [Ruby Bug#22276] alias in a module falls back to Object even in classes not inheriting from Object Issue #22276 has been updated by shugo (Shugo Maeda). luke-gru (Luke Gruber) wrote in #note-2: > I think nothing should be decided on this in isolation. We should discuss this and [22273](https://bugs.ruby-lang.org/issues/22273) together, as they are related as @shugo mentions. We discussed this ticket together with #22273 at the developer meeting. Matz decided the direction of this ticket as in #note-3, but he wanted more time to think about #22273. ---------------------------------------- Bug #22276: alias in a module falls back to Object even in classes not inheriting from Object https://bugs.ruby-lang.org/issues/22276#change-118893 * Author: shugo (Shugo Maeda) * Status: Open * ruby -v: ruby 4.1.0dev (2026-08-28T07:43:16Z master 69b49ac7ae) +PRISM [x86_64-linux] * Backport: 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- When `alias` (or `alias_method`) is used in a module and the method is not found in the module, `alias` searches the method from `Object`. So a module can alias a method of `Kernel` or `Object`, and the alias works even if the module is later included in a class that does not have `Object` and `Kernel` as ancestors: ```ruby module M alias foo puts public :foo end class X < BasicObject include ::M end X.new.foo("hello") #=> hello ``` `X` does not include `Kernel`, but `X.new.foo` calls `Kernel#puts`. This fallback comes from Ruby 1.8, where `Object` was the root class, so every class that includes a module always had `Object` and `Kernel` as ancestors. Since Ruby 1.9 introduced `BasicObject`, this is no longer true, but the fallback is unchanged. As discussed in #22273, a module should be able to alias only its own methods and its ancestors' methods, and `Object` is not an ancestor of a module. This behavior is intentional in the current implementation. There are tests for it (`test_alias_in_module` in test/ruby/test_alias.rb for #9663, and "accesses a method defined on Object from Kernel" in spec/ruby/core/module/alias_method_spec.rb), and the documentation of `Module#alias_method` has an example `module Mod; alias_method :orig_exit, :exit; end`. So code like `module M; alias orig_to_s to_s; end` exists, and simply raising `NameError` will break it. Possible fixes: 1. Remove the fallback and raise `NameError`. This breaks existing code. 2. Do not resolve the method at alias time. Instead, resolve it at call time from the ancestors of the receiver's class, like ZSUPER methods. Existing code that includes the module in a subclass of `Object` keeps working, and `X.new.foo` above raises `NoMethodError`. 3. Keep the current behavior and document it. I think 2 is the best choice for compatibility. -- 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/lists/ruby-core.ml.ruby-lang.org/