From: "Eregon (Benoit Daloze)" Date: 2022-08-15T13:22:20+00:00 Subject: [ruby-core:109486] [Ruby master Bug#18751] Regression on master for Method#== when comparing public with private method Issue #18751 has been updated by Eregon (Benoit Daloze). Here is a simplified script which does not depend on Class.new == Class#new: ```ruby class C class << self alias_method :n, :new private :new end end p C.method(:n) == C.method(:new) # => true puts p C.method(:n) == Class.method(:new) # => false p C.method(:n) == Class.instance_method(:new).bind(C) # => true puts p C.method(:new) == Class.method(:new) # => false p C.method(:new) == Class.instance_method(:new).bind(C) # => true, BUT false on master p [C.method(:new), Class.instance_method(:new).bind(C)] # => [#(Class)#new(*)>, #(Class)#new(*)>] ``` Based on this PR to fix this by no longer hiding ZSUPER methods: https://github.com/ruby/ruby/pull/6242, I think we should add a new method on Method and UnboundMethod to check if they have the same definition. Because otherwise naturally a method with a different visibility is a separate method, and making them the same with == seems wrong. Maybe simply `{Method,UnboundMethod}#same_definition?(other)`. I would also allow either Method or UnboundMethod as the argument, so there is no need to bind/unbind to compare. ---------------------------------------- Bug #18751: Regression on master for Method#== when comparing public with private method https://bugs.ruby-lang.org/issues/18751#change-98654 * Author: Eregon (Benoit Daloze) * Status: Open * Priority: Normal * ruby -v: ruby 3.2.0dev (2022-04-23T02:59:20Z master e142bea799) [x86_64-linux] * Backport: 2.7: DONTNEED, 3.0: DONTNEED, 3.1: DONTNEED ---------------------------------------- This script repros: ```ruby class C class << self alias_method :n, :new private :new end end p C.method(:n) == C.method(:new) # => true puts p C.method(:n) == Class.method(:new) # => false p C.method(:n) == Class.method(:new).unbind.bind(C) # => true puts p C.method(:new) == Class.method(:new) # => false p C.method(:new) == Class.method(:new).unbind.bind(C) # => true, BUT false on master p C.method(:new) == Class.instance_method(:new).bind(C) # => true, BUT false on master p [C.method(:new), Class.instance_method(:new).bind(C)] # => [#(Class)#new(*)>, #(Class)#new(*)>] ``` So this prints the expected results on 2.7.5, 3.0.3, 3.1.1 but not on master, which seems a regression. Notably this breaks the pattern discussed in https://bugs.ruby-lang.org/issues/18729#note-5, and it means there is no way to find out if two methods share the same "definition/logic/def", which is a big limitation. -- https://bugs.ruby-lang.org/ Unsubscribe: