Forum: Ruby-core Including a module already present in ancestors should not be ignored

F1d6cc2b735bfd82c8773172da2aeab9?d=identicon&s=25 Nobuyoshi Nakada (nobu)
on 2012-11-30 11:05
(Received via mailing list)
Issue #1586 has been updated by nobu (Nobuyoshi Nakada).

Priority changed from High to Normal
Target version changed from 2.0.0 to next minor

This would cause compatibility issue, in some cases, when a module is
included twice but it expects it never get called twice or more by
super.  Or, if a method of the module does not call super, the super
calls stops unexpectedly.

One idea is to introduce a method of Module which tells a module is
multi-time includable.

----------------------------------------
Feature #1586: Including a module already present in ancestors should
not be ignored
https://bugs.ruby-lang.org/issues/1586#change-34210

Author: bitsweat (Jeremy Kemper)
Status: Assigned
Priority: Normal
Assignee: nobu (Nobuyoshi Nakada)
Category: core
Target version: next minor


=begin
 The scenario:
 * I include Foo in Numeric to provide #bar
 * Some other library includes a module in Float to provide #bar
 * So I include Foo in Float to use my #bar
 * But including Foo in Float is ignored since it's already in the
ancestor chain

 I think it should be added to the ancestor chain, even if it's already
present, since I may want to override some other method earlier in the
ancestor chain.

 # Including a module already included in a superclass is ignored
 >> module Foo; end
 => nil
 >> class Numeric; include Foo; end
 => Numeric
 >> Float.ancestors
 => [Float, Precision, Numeric, Foo, Comparable, Object, Kernel]
 >> class Float; include Foo; end
 => Float
 >> Float.ancestors
 => [Float, Precision, Numeric, Foo, Comparable, Object, Kernel]

 # Reversing the order of inclusion works as expected
 >> module Foo; end
 => nil
 >> class Float; include Foo; end
 => Float
 >> Float.ancestors
 => [Float, Foo, Precision, Numeric, Comparable, Object, Kernel]
 >> class Numeric; include Foo; end
 => Numeric
 >> Float.ancestors
 => [Float, Foo, Precision, Numeric, Foo, Comparable, Object, Kernel]

 # And so does including a dupe of the existing module in the subclass
 >> module Foo; end
 => nil
 >> class Numeric; include Foo; end
 => Numeric
 >> Float.ancestors
 => [Float, Precision, Numeric, Foo, Comparable, Object, Kernel]
 >> class Float; include Foo.dup; end
 => Float
 >> Float.ancestors
 => [Float, #<Module:0x19bcd40>, Precision, Numeric, Foo, Comparable,
Object, Kernel]
=end
This topic is locked and can not be replied to.