Issue #22276 has been updated by luke-gru (Luke Gruber). 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. ---------------------------------------- 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-118776 * 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/