Bug #17038
closedOn master, ancestry edits can lead to duplicates in Module#ancestors
Description
Running the following script on master(935d0b3d05dfc8b30bba505792129bf0e33ebe3b),
A
appears three times in the lookup chain of C
and A#foo
is called multiple
times with super
.
module A
def foo
[:a] + super
end
end
module B
def foo
[:b] + super
end
end
class Object
def foo
[:object]
end
end
module C
def foo
[:c] + super
end
end
class D
prepend A
include C
include B
def foo
[:d] + super
end
end
B.include A
C.include A
p D.ancestors
p D.new.foo
p RUBY_REVISION
__END__
[A, D, B, A, C, A, Object, Kernel, BasicObject]
[:a, :d, :b, :a, :c, :a, :object]
"935d0b3d05dfc8b30bba505792129bf0e33ebe3b"
This change was introduced in #9573. Is this behavior intentional?
In my opinion it's a bit odd since it's not possible to have duplicates
in the lookup chain on released versions. Allowing duplicates can
surprise peopole that are used to not having duplicates and lead to bugs.
If A#foo
had side effects, for example, calling it multiple times
could be undesirable.
Also, logically it doesn't make sense to have a module be the ancestor of itself.
Comparison operators make less sense with this new setup.
Updated by alanwu (Alan Wu) over 4 years ago
- Subject changed from On master, ancestry edits can lead to duplicates in Module#ancestor to On master, ancestry edits can lead to duplicates in Module#ancestors
Updated by jeremyevans0 (Jeremy Evans) over 4 years ago
I believe it's always been possible to have duplicates in ancestors, even before this change:
class A
end
class B < A
end
module C
end
B.include C
A.include C
B.ancestors
# => [B, C, A, C, Object, Kernel, BasicObject]
Making include/prepend affect iclasses certainly makes duplicates in ancestors more likely, though.
I don't think this is a bug. If you think it is a bug, can you describe what you consider the correct behavior to be?
Updated by marcandre (Marc-Andre Lafortune) over 4 years ago
I imagine that @alanwu (Alan Wu) feels the example code should behave the same way if the include
were done sooner or later.
Jeremy Evans is right, the issue has existed for a long time.
I would prefer if we could always include a module multiple times (at different levels).
See this discussion: https://bugs.ruby-lang.org/issues/1586
Updated by alanwu (Alan Wu) over 4 years ago
I believe it's always been possible to have duplicates in ancestors, even before this change
Thank you for the example; I stand corrected. I made the ticket because I thought we were introducing
brand new potential failure modes into user code. It's not a concern, it looks like.
I don't really have a preference for whether duplicates should be allowed.
Updated by marcandre (Marc-Andre Lafortune) over 4 years ago
- Status changed from Open to Rejected
Note that this change is listed in the NEWS
I'm thus closing this.