ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:124741] [Ruby Bug#21873] `UnboundMethod#==` returns false for methods obtained via extend + unbind
@ 2026-02-09 20:08 mdalessio (Mike Dalessio) via ruby-core
  2026-02-09 20:09 ` [ruby-core:124742] " mdalessio (Mike Dalessio) via ruby-core
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: mdalessio (Mike Dalessio) via ruby-core @ 2026-02-09 20:08 UTC (permalink / raw)
  To: ruby-core; +Cc: mdalessio (Mike Dalessio)

Issue #21873 has been reported by mdalessio (Mike Dalessio).

----------------------------------------
Bug #21873: `UnboundMethod#==` returns false for methods obtained via extend + unbind
https://bugs.ruby-lang.org/issues/21873

* Author: mdalessio (Mike Dalessio)
* Status: Open
* Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN
----------------------------------------
## Description

`UnboundMethod#==` returns `false` when comparing a module's instance method against the same method obtained via `Method#unbind` on a class that includes or extends that module, despite having the same owner and source location.

```ruby
module MyMethods
  def hello = "hello"
end

class Base
  extend MyMethods
end

from_module = MyMethods.instance_method(:hello)
from_unbind = Base.method(:hello).unbind

p from_module.owner == from_unbind.owner                     #=> true
p from_module.source_location == from_unbind.source_location #=> true
p from_module.inspect == from_unbind.inspect                 #=> true

p from_module == from_unbind                                 #=> false (expected true)
```

## Diagnosis

`method_eq` compares method entries using `method_entry_defined_class`. For methods mixed in via `include`/`extend`, the "defined class" will be an ICLASS and not the original class/module. In the example above, `method_eq` is comparing a module's ICLASS entry against the module, and that will always be false.

Related: #18798 (fixed by @ko1 in 59e389af).





-- 
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/

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [ruby-core:124742] [Ruby Bug#21873] `UnboundMethod#==` returns false for methods obtained via extend + unbind
  2026-02-09 20:08 [ruby-core:124741] [Ruby Bug#21873] `UnboundMethod#==` returns false for methods obtained via extend + unbind mdalessio (Mike Dalessio) via ruby-core
@ 2026-02-09 20:09 ` mdalessio (Mike Dalessio) via ruby-core
  2026-02-10 15:16 ` [ruby-core:124763] [Ruby Bug#21873] `UnboundMethod#==` returns false for methods from included/extended modules Eregon (Benoit Daloze) via ruby-core
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: mdalessio (Mike Dalessio) via ruby-core @ 2026-02-09 20:09 UTC (permalink / raw)
  To: ruby-core; +Cc: mdalessio (Mike Dalessio)

Issue #21873 has been updated by mdalessio (Mike Dalessio).


A potential fix for this might be:

```diff
diff --git a/proc.c b/proc.c
index f0cdcae7..67963a1b 100644
--- a/proc.c
+++ b/proc.c
@@ -2006,6 +2006,8 @@ method_eq(VALUE method, VALUE other)

     klass1 = method_entry_defined_class(m1->me);
     klass2 = method_entry_defined_class(m2->me);
+    if (RB_TYPE_P(klass1, T_ICLASS)) klass1 = RBASIC_CLASS(klass1);
+    if (RB_TYPE_P(klass2, T_ICLASS)) klass2 = RBASIC_CLASS(klass2);

     if (!rb_method_entry_eq(m1->me, m2->me) ||
         klass1 != klass2 ||
```


----------------------------------------
Bug #21873: `UnboundMethod#==` returns false for methods obtained via extend + unbind
https://bugs.ruby-lang.org/issues/21873#change-116343

* Author: mdalessio (Mike Dalessio)
* Status: Open
* Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN
----------------------------------------
## Description

`UnboundMethod#==` returns `false` when comparing a module's instance method against the same method obtained via `Method#unbind` on a class that includes or extends that module, despite having the same owner and source location.

```ruby
module MyMethods
  def hello = "hello"
end

class Base
  extend MyMethods
end

from_module = MyMethods.instance_method(:hello)
from_unbind = Base.method(:hello).unbind

p from_module.owner == from_unbind.owner                     #=> true
p from_module.source_location == from_unbind.source_location #=> true
p from_module.inspect == from_unbind.inspect                 #=> true

p from_module == from_unbind                                 #=> false (expected true)
```

## Diagnosis

`method_eq` compares method entries using `method_entry_defined_class`. For methods mixed in via `include`/`extend`, the "defined class" will be an ICLASS and not the original class/module. In the example above, `method_eq` is comparing a module's ICLASS entry against the module, and that will always be false.

Related: #18798 (fixed by @ko1 in 59e389af).





-- 
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/

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [ruby-core:124763] [Ruby Bug#21873] `UnboundMethod#==` returns false for methods from included/extended modules
  2026-02-09 20:08 [ruby-core:124741] [Ruby Bug#21873] `UnboundMethod#==` returns false for methods obtained via extend + unbind mdalessio (Mike Dalessio) via ruby-core
  2026-02-09 20:09 ` [ruby-core:124742] " mdalessio (Mike Dalessio) via ruby-core
@ 2026-02-10 15:16 ` Eregon (Benoit Daloze) via ruby-core
  2026-02-10 18:36 ` [ruby-core:124765] " k0kubun (Takashi Kokubun) via ruby-core
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Eregon (Benoit Daloze) via ruby-core @ 2026-02-10 15:16 UTC (permalink / raw)
  To: ruby-core; +Cc: Eregon (Benoit Daloze)

Issue #21873 has been updated by Eregon (Benoit Daloze).

Backport changed from 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN to 3.2: REQUIRED, 3.3: REQUIRED, 3.4: REQUIRED, 4.0: REQUIRED

Marking as REQUIRED to backport to all versions since all versions seem affected.

----------------------------------------
Bug #21873: `UnboundMethod#==` returns false for methods from included/extended modules
https://bugs.ruby-lang.org/issues/21873#change-116370

* Author: mdalessio (Mike Dalessio)
* Status: Closed
* Backport: 3.2: REQUIRED, 3.3: REQUIRED, 3.4: REQUIRED, 4.0: REQUIRED
----------------------------------------
## Description

`UnboundMethod#==` returns `false` when comparing a module's instance method against the same method obtained via `Method#unbind` on a class that includes or extends that module, despite having the same owner and source location.

```ruby
module MyMethods
  def hello = "hello"
end

class Base
  extend MyMethods
end

from_module = MyMethods.instance_method(:hello)
from_unbind = Base.method(:hello).unbind

p from_module.owner == from_unbind.owner                     #=> true
p from_module.source_location == from_unbind.source_location #=> true
p from_module.inspect == from_unbind.inspect                 #=> true

p from_module == from_unbind                                 #=> false (expected true)
```

## Diagnosis

`method_eq` compares method entries using `method_entry_defined_class`. For methods mixed in via `include`/`extend`, the "defined class" will be an ICLASS and not the original class/module. In the example above, `method_eq` is comparing a module's ICLASS entry against the module, and that will always be false.

Related: #18798 (fixed by @ko1 in 59e389af).





-- 
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/

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [ruby-core:124765] [Ruby Bug#21873] `UnboundMethod#==` returns false for methods from included/extended modules
  2026-02-09 20:08 [ruby-core:124741] [Ruby Bug#21873] `UnboundMethod#==` returns false for methods obtained via extend + unbind mdalessio (Mike Dalessio) via ruby-core
  2026-02-09 20:09 ` [ruby-core:124742] " mdalessio (Mike Dalessio) via ruby-core
  2026-02-10 15:16 ` [ruby-core:124763] [Ruby Bug#21873] `UnboundMethod#==` returns false for methods from included/extended modules Eregon (Benoit Daloze) via ruby-core
@ 2026-02-10 18:36 ` k0kubun (Takashi Kokubun) via ruby-core
  2026-02-11 10:00 ` [ruby-core:124768] " byroot (Jean Boussier) via ruby-core
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: k0kubun (Takashi Kokubun) via ruby-core @ 2026-02-10 18:36 UTC (permalink / raw)
  To: ruby-core; +Cc: k0kubun (Takashi Kokubun)

Issue #21873 has been updated by k0kubun (Takashi Kokubun).

Backport changed from 3.2: REQUIRED, 3.3: REQUIRED, 3.4: REQUIRED, 4.0: REQUIRED to 3.2: REQUIRED, 3.3: REQUIRED, 3.4: REQUIRED, 4.0: DONE

ruby_4_0 commit:0768f08caff514b0ba616dc26d76aad90577eefe.

----------------------------------------
Bug #21873: `UnboundMethod#==` returns false for methods from included/extended modules
https://bugs.ruby-lang.org/issues/21873#change-116374

* Author: mdalessio (Mike Dalessio)
* Status: Closed
* Backport: 3.2: REQUIRED, 3.3: REQUIRED, 3.4: REQUIRED, 4.0: DONE
----------------------------------------
## Description

`UnboundMethod#==` returns `false` when comparing a module's instance method against the same method obtained via `Method#unbind` on a class that includes or extends that module, despite having the same owner and source location.

```ruby
module MyMethods
  def hello = "hello"
end

class Base
  extend MyMethods
end

from_module = MyMethods.instance_method(:hello)
from_unbind = Base.method(:hello).unbind

p from_module.owner == from_unbind.owner                     #=> true
p from_module.source_location == from_unbind.source_location #=> true
p from_module.inspect == from_unbind.inspect                 #=> true

p from_module == from_unbind                                 #=> false (expected true)
```

## Diagnosis

`method_eq` compares method entries using `method_entry_defined_class`. For methods mixed in via `include`/`extend`, the "defined class" will be an ICLASS and not the original class/module. In the example above, `method_eq` is comparing a module's ICLASS entry against the module, and that will always be false.

Related: #18798 (fixed by @ko1 in 59e389af).





-- 
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/

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [ruby-core:124768] [Ruby Bug#21873] `UnboundMethod#==` returns false for methods from included/extended modules
  2026-02-09 20:08 [ruby-core:124741] [Ruby Bug#21873] `UnboundMethod#==` returns false for methods obtained via extend + unbind mdalessio (Mike Dalessio) via ruby-core
                   ` (2 preceding siblings ...)
  2026-02-10 18:36 ` [ruby-core:124765] " k0kubun (Takashi Kokubun) via ruby-core
@ 2026-02-11 10:00 ` byroot (Jean Boussier) via ruby-core
  2026-03-06 15:27 ` [ruby-core:124939] " luke-gru (Luke Gruber) via ruby-core
  2026-03-07  5:42 ` [ruby-core:124946] " nagachika (Tomoyuki Chikanaga) via ruby-core
  5 siblings, 0 replies; 7+ messages in thread
From: byroot (Jean Boussier) via ruby-core @ 2026-02-11 10:00 UTC (permalink / raw)
  To: ruby-core; +Cc: byroot (Jean Boussier)

Issue #21873 has been updated by byroot (Jean Boussier).

Backport changed from 3.2: REQUIRED, 3.3: REQUIRED, 3.4: REQUIRED, 4.0: DONE to 3.2: WONTFIX, 3.3: REQUIRED, 3.4: REQUIRED, 4.0: DONE

3.2 is in security only maintenance though.

----------------------------------------
Bug #21873: `UnboundMethod#==` returns false for methods from included/extended modules
https://bugs.ruby-lang.org/issues/21873#change-116377

* Author: mdalessio (Mike Dalessio)
* Status: Closed
* Backport: 3.2: WONTFIX, 3.3: REQUIRED, 3.4: REQUIRED, 4.0: DONE
----------------------------------------
## Description

`UnboundMethod#==` returns `false` when comparing a module's instance method against the same method obtained via `Method#unbind` on a class that includes or extends that module, despite having the same owner and source location.

```ruby
module MyMethods
  def hello = "hello"
end

class Base
  extend MyMethods
end

from_module = MyMethods.instance_method(:hello)
from_unbind = Base.method(:hello).unbind

p from_module.owner == from_unbind.owner                     #=> true
p from_module.source_location == from_unbind.source_location #=> true
p from_module.inspect == from_unbind.inspect                 #=> true

p from_module == from_unbind                                 #=> false (expected true)
```

## Diagnosis

`method_eq` compares method entries using `method_entry_defined_class`. For methods mixed in via `include`/`extend`, the "defined class" will be an ICLASS and not the original class/module. In the example above, `method_eq` is comparing a module's ICLASS entry against the module, and that will always be false.

Related: #18798 (fixed by @ko1 in 59e389af).





-- 
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/

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [ruby-core:124939] [Ruby Bug#21873] `UnboundMethod#==` returns false for methods from included/extended modules
  2026-02-09 20:08 [ruby-core:124741] [Ruby Bug#21873] `UnboundMethod#==` returns false for methods obtained via extend + unbind mdalessio (Mike Dalessio) via ruby-core
                   ` (3 preceding siblings ...)
  2026-02-11 10:00 ` [ruby-core:124768] " byroot (Jean Boussier) via ruby-core
@ 2026-03-06 15:27 ` luke-gru (Luke Gruber) via ruby-core
  2026-03-07  5:42 ` [ruby-core:124946] " nagachika (Tomoyuki Chikanaga) via ruby-core
  5 siblings, 0 replies; 7+ messages in thread
From: luke-gru (Luke Gruber) via ruby-core @ 2026-03-06 15:27 UTC (permalink / raw)
  To: ruby-core; +Cc: luke-gru (Luke Gruber)

Issue #21873 has been updated by luke-gru (Luke Gruber).


3.4 backport PR: https://github.com/ruby/ruby/pull/16326

----------------------------------------
Bug #21873: `UnboundMethod#==` returns false for methods from included/extended modules
https://bugs.ruby-lang.org/issues/21873#change-116613

* Author: mdalessio (Mike Dalessio)
* Status: Closed
* Backport: 3.2: WONTFIX, 3.3: REQUIRED, 3.4: REQUIRED, 4.0: DONE
----------------------------------------
## Description

`UnboundMethod#==` returns `false` when comparing a module's instance method against the same method obtained via `Method#unbind` on a class that includes or extends that module, despite having the same owner and source location.

```ruby
module MyMethods
  def hello = "hello"
end

class Base
  extend MyMethods
end

from_module = MyMethods.instance_method(:hello)
from_unbind = Base.method(:hello).unbind

p from_module.owner == from_unbind.owner                     #=> true
p from_module.source_location == from_unbind.source_location #=> true
p from_module.inspect == from_unbind.inspect                 #=> true

p from_module == from_unbind                                 #=> false (expected true)
```

## Diagnosis

`method_eq` compares method entries using `method_entry_defined_class`. For methods mixed in via `include`/`extend`, the "defined class" will be an ICLASS and not the original class/module. In the example above, `method_eq` is comparing a module's ICLASS entry against the module, and that will always be false.

Related: #18798 (fixed by @ko1 in 59e389af).





-- 
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/

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [ruby-core:124946] [Ruby Bug#21873] `UnboundMethod#==` returns false for methods from included/extended modules
  2026-02-09 20:08 [ruby-core:124741] [Ruby Bug#21873] `UnboundMethod#==` returns false for methods obtained via extend + unbind mdalessio (Mike Dalessio) via ruby-core
                   ` (4 preceding siblings ...)
  2026-03-06 15:27 ` [ruby-core:124939] " luke-gru (Luke Gruber) via ruby-core
@ 2026-03-07  5:42 ` nagachika (Tomoyuki Chikanaga) via ruby-core
  5 siblings, 0 replies; 7+ messages in thread
From: nagachika (Tomoyuki Chikanaga) via ruby-core @ 2026-03-07  5:42 UTC (permalink / raw)
  To: ruby-core; +Cc: nagachika (Tomoyuki Chikanaga)

Issue #21873 has been updated by nagachika (Tomoyuki Chikanaga).

Backport changed from 3.2: WONTFIX, 3.3: DONE, 3.4: REQUIRED, 4.0: DONE to 3.2: WONTFIX, 3.3: DONE, 3.4: DONE, 4.0: DONE

ruby_3_4: merged at commit:0097b87b1e2c6aa60489527e421e8bf2e2791d69.

----------------------------------------
Bug #21873: `UnboundMethod#==` returns false for methods from included/extended modules
https://bugs.ruby-lang.org/issues/21873#change-116630

* Author: mdalessio (Mike Dalessio)
* Status: Closed
* Backport: 3.2: WONTFIX, 3.3: DONE, 3.4: DONE, 4.0: DONE
----------------------------------------
## Description

`UnboundMethod#==` returns `false` when comparing a module's instance method against the same method obtained via `Method#unbind` on a class that includes or extends that module, despite having the same owner and source location.

```ruby
module MyMethods
  def hello = "hello"
end

class Base
  extend MyMethods
end

from_module = MyMethods.instance_method(:hello)
from_unbind = Base.method(:hello).unbind

p from_module.owner == from_unbind.owner                     #=> true
p from_module.source_location == from_unbind.source_location #=> true
p from_module.inspect == from_unbind.inspect                 #=> true

p from_module == from_unbind                                 #=> false (expected true)
```

## Diagnosis

`method_eq` compares method entries using `method_entry_defined_class`. For methods mixed in via `include`/`extend`, the "defined class" will be an ICLASS and not the original class/module. In the example above, `method_eq` is comparing a module's ICLASS entry against the module, and that will always be false.

Related: #18798 (fixed by @ko1 in 59e389af).





-- 
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/

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-03-07  5:43 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-09 20:08 [ruby-core:124741] [Ruby Bug#21873] `UnboundMethod#==` returns false for methods obtained via extend + unbind mdalessio (Mike Dalessio) via ruby-core
2026-02-09 20:09 ` [ruby-core:124742] " mdalessio (Mike Dalessio) via ruby-core
2026-02-10 15:16 ` [ruby-core:124763] [Ruby Bug#21873] `UnboundMethod#==` returns false for methods from included/extended modules Eregon (Benoit Daloze) via ruby-core
2026-02-10 18:36 ` [ruby-core:124765] " k0kubun (Takashi Kokubun) via ruby-core
2026-02-11 10:00 ` [ruby-core:124768] " byroot (Jean Boussier) via ruby-core
2026-03-06 15:27 ` [ruby-core:124939] " luke-gru (Luke Gruber) via ruby-core
2026-03-07  5:42 ` [ruby-core:124946] " nagachika (Tomoyuki Chikanaga) via ruby-core

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).