https://redmine.ruby-lang.org/https://redmine.ruby-lang.org/favicon.ico?17113305112014-02-27T06:23:49ZRuby Issue Tracking SystemRuby master - Bug #9573: descendants of a module don't gain its future ancestors, but descendants of a class, dohttps://redmine.ruby-lang.org/issues/9573?journal_id=455022014-02-27T06:23:49Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/45502/diff?detail_id=32889">diff</a>)</li></ul><p>First Last wrote:</p>
<blockquote>
<p>so 2 issues:</p>
<ol>
<li>It would seem natural that in dynamic language, dynamically added ancestors should propagate to descendants</li>
</ol>
</blockquote>
<p>It's a longstanding issue, a descendant knows its ancestors, but an ancestor doesn't know its descendants.</p>
<blockquote>
<ol start="2">
<li>Why is there a difference in ancestor propagation between modules and classes</li>
</ol>
</blockquote>
<p>It is not between modules and classes, but caused by the order of inheritance and including.</p> Ruby master - Bug #9573: descendants of a module don't gain its future ancestors, but descendants of a class, dohttps://redmine.ruby-lang.org/issues/9573?journal_id=455032014-02-27T06:43:38Zrits (First Last)
<ul></ul><p>Nobuyoshi Nakada wrote:</p>
<blockquote>
<p>First Last wrote:</p>
<blockquote>
<p>so 2 issues:</p>
<ol>
<li>It would seem natural that in dynamic language, dynamically added ancestors should propagate to descendants</li>
</ol>
</blockquote>
<p>It's a longstanding issue, a descendant knows its ancestors, but an ancestor doesn't know its descendants.</p>
</blockquote>
<p>Is it the case that ancestors are cached in each descendant? So that it does not actually walk the ancestor tree each time. If so, is there any way to invalidate this cache for a given class or all, and have it reevaluate the ancestors?</p>
<blockquote>
<blockquote>
<ol start="2">
<li>Why is there a difference in ancestor propagation between modules and classes</li>
</ol>
</blockquote>
<p>It is not between modules and classes, but caused by the order of inheritance and including.</p>
</blockquote>
<p>Please clarify. Mod1 is included in Class1 after Class2 extends Class1 and yet Class2 somehow learns of its new grandparent, Mod1. How does that happen if ancestors (Class1) do not know their descendants (Class2). So there is a difference, an ancestor added to a class, propagates to the descendant of this class, but an ancestor added to a module does not propagate to the descendant of this module.</p> Ruby master - Bug #9573: descendants of a module don't gain its future ancestors, but descendants of a class, dohttps://redmine.ruby-lang.org/issues/9573?journal_id=455042014-02-27T08:30:17Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>First Last wrote:</p>
<blockquote>
<blockquote>
<blockquote>
<ol>
<li>It would seem natural that in dynamic language, dynamically added ancestors should propagate to descendants</li>
</ol>
</blockquote>
<p>It's a longstanding issue, a descendant knows its ancestors, but an ancestor doesn't know its descendants.</p>
</blockquote>
<p>Is it the case that ancestors are cached in each descendant? So that it does not actually walk the ancestor tree each time. If so, is there any way to invalidate this cache for a given class or all, and have it reevaluate the ancestors?</p>
</blockquote>
<p>An included module is shared using an internal class (called as IClass), and IClasses are copied for each trees.<br>
Now subclasses/submodules are maintained in each classes/modules for method cache validation, so it may be possible.</p>
<blockquote>
<blockquote>
<blockquote>
<ol start="2">
<li>Why is there a difference in ancestor propagation between modules and classes</li>
</ol>
</blockquote>
<p>It is not between modules and classes, but caused by the order of inheritance and including.</p>
</blockquote>
<p>Please clarify. Mod1 is included in Class1 after Class2 extends Class1 and yet Class2 somehow learns of its new grandparent, Mod1. How does that happen if ancestors (Class1) do not know their descendants (Class2). So there is a difference, an ancestor added to a class, propagates to the descendant of this class, but an ancestor added to a module does not propagate to the descendant of this module.</p>
</blockquote>
<p><code>Class1</code> only knows <code>Mod1</code>, and its ancestor tree is copied into <code>Class2</code>.<br>
And ditto for including a module.</p> Ruby master - Bug #9573: descendants of a module don't gain its future ancestors, but descendants of a class, dohttps://redmine.ruby-lang.org/issues/9573?journal_id=455052014-02-27T10:12:06Zrits (First Last)
<ul></ul><p>Nobuyoshi Nakada wrote:</p>
<blockquote>
<p>First Last wrote:</p>
<blockquote>
<p>Please clarify. Mod1 is included in Class1 after Class2 extends Class1 and yet Class2 somehow learns of its new grandparent, Mod1. How does that happen if ancestors (Class1) do not know their descendants (Class2). So there is a difference, an ancestor added to a class, propagates to the descendant of this class, but an ancestor added to a module does not propagate to the descendant of this module.</p>
</blockquote>
<p><code>Class1</code> only knows <code>Mod1</code>, and its ancestor tree is copied into <code>Class2</code>.<br>
And ditto for including a module.</p>
</blockquote>
<p>I am inferring that the ancestor tree is copied into Class2 when it extends Class1, yes?<br>
But at this time Mod1 has not yet been included, so how does Class2 learn of Mod1?</p>
<p>and why is the situation different with modules?</p>
<p>Do you see what I am pointing out, an ancestor added to a class, propagates to the <strong>past</strong> descendant of this class (Class2 extends Class1 <strong>before</strong> Mod1 is included in Class1), but an ancestor added to a module does not propagate to the <strong>past</strong> descendant of this module.</p> Ruby master - Bug #9573: descendants of a module don't gain its future ancestors, but descendants of a class, dohttps://redmine.ruby-lang.org/issues/9573?journal_id=455082014-02-28T00:11:08Zrits (First Last)
<ul></ul><p>First Last wrote:</p>
<blockquote>
<p>Nobuyoshi Nakada wrote:</p>
<blockquote>
<p><code>Class1</code> only knows <code>Mod1</code>, and its ancestor tree is copied into <code>Class2</code>.<br>
And ditto for including a module.</p>
</blockquote>
<p>I am inferring that the ancestor tree is copied into Class2 when it extends Class1, yes?<br>
But at this time Mod1 has not yet been included, so how does Class2 learn of Mod1?</p>
<p>and why is the situation different with modules?</p>
<p>Do you see what I am pointing out, an ancestor added to a class, propagates to the <strong>past</strong> descendant of this class (Class2 extends Class1 <strong>before</strong> Mod1 is included in Class1), but an ancestor added to a module does not propagate to the <strong>past</strong> descendant of this module.</p>
</blockquote>
<p>Can someone please explain this phenomenon.</p> Ruby master - Bug #9573: descendants of a module don't gain its future ancestors, but descendants of a class, dohttps://redmine.ruby-lang.org/issues/9573?journal_id=456362014-03-05T16:07:23Zrits (First Last)
<ul></ul><p>First Last wrote:</p>
<blockquote>
<p>First Last wrote:</p>
<blockquote>
<p>Nobuyoshi Nakada wrote:</p>
<blockquote>
<p><code>Class1</code> only knows <code>Mod1</code>, and its ancestor tree is copied into <code>Class2</code>.<br>
And ditto for including a module.</p>
</blockquote>
<p>I am inferring that the ancestor tree is copied into Class2 when it extends Class1, yes?<br>
But at this time Mod1 has not yet been included, so how does Class2 learn of Mod1?</p>
<p>and why is the situation different with modules?</p>
<p>Do you see what I am pointing out, an ancestor added to a class, propagates to the <strong>past</strong> descendant of this class (Class2 extends Class1 <strong>before</strong> Mod1 is included in Class1), but an ancestor added to a module does not propagate to the <strong>past</strong> descendant of this module.</p>
</blockquote>
<p>Can someone please explain this phenomenon.</p>
</blockquote> Ruby master - Bug #9573: descendants of a module don't gain its future ancestors, but descendants of a class, dohttps://redmine.ruby-lang.org/issues/9573?journal_id=457672014-03-13T19:45:48Zrits (First Last)
<ul></ul><p>First Last wrote:</p>
<blockquote>
<p>First Last wrote:</p>
<blockquote>
<p>First Last wrote:</p>
<blockquote>
<p>Nobuyoshi Nakada wrote:</p>
<blockquote>
<p><code>Class1</code> only knows <code>Mod1</code>, and its ancestor tree is copied into <code>Class2</code>.<br>
And ditto for including a module.</p>
</blockquote>
<p>I am inferring that the ancestor tree is copied into Class2 when it extends Class1, yes?<br>
But at this time Mod1 has not yet been included, so how does Class2 learn of Mod1?</p>
<p>and why is the situation different with modules?</p>
<p>Do you see what I am pointing out, an ancestor added to a class, propagates to the <strong>past</strong> descendant of this class (Class2 extends Class1 <strong>before</strong> Mod1 is included in Class1), but an ancestor added to a module does not propagate to the <strong>past</strong> descendant of this module.</p>
</blockquote>
<p>Can someone please explain this phenomenon.</p>
</blockquote>
</blockquote>
<p>What is the objection to explaining how this works?</p> Ruby master - Bug #9573: descendants of a module don't gain its future ancestors, but descendants of a class, dohttps://redmine.ruby-lang.org/issues/9573?journal_id=457682014-03-13T20:34:51Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul></ul><p>First Last wrote:</p>
<blockquote>
<p>What is the objection to explaining how this works?</p>
</blockquote>
<p>nobu explained how it works. However, as he is not a native English speaker, let me attempt to clarify.</p>
<p>In ruby, there exist pseudo-copies of modules called iclasses. These copies share the same variable(class variable/instance variable/constant) tables and the same method tables, but have a different super pointer in their C struct. iclasses are made when you attempt to include a module in another module or class.</p>
<p>When you do:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">module</span> <span class="nn">M0</span><span class="p">;</span> <span class="k">end</span>
<span class="k">module</span> <span class="nn">M1</span>
<span class="kp">include</span> <span class="no">M0</span>
<span class="k">end</span>
</code></pre>
<p>This creates a module M1 that includes an iclass of M0 (notated below as i0M0) in its inheritance list. For a module, the inheritance list is the the super pointer in struct RClass).</p>
<p>When you do:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">A</span>
<span class="kp">include</span> <span class="no">M1</span>
<span class="k">end</span>
</code></pre>
<p>What happens is iclasses of M1 and i0M0 are made (notated below as i0M1, i1M0). So method lookup for an instance of A will be:</p>
<pre><code>A -> i0M1 -> i1M0 -> Object
</code></pre>
<p>Here's how the super pointers for the struct RClass should look:</p>
<pre><code>M0: NULL
i0M0: NULL
M1: i0M0
i1M0: Object
i0M1: i1M0
A: i0M1
</code></pre>
<p>When you do:</p>
<pre><code>module M2; end
M1.include M2
</code></pre>
<p>This creates an iclass of M2 (i0M2) and updates the super pointer in M1, as shown:</p>
<pre><code>M1: i0M2
i0M2: i0M0
i0M0: NULL
</code></pre>
<p>However, it has no effect on any of the iclasses of M1 already created.</p>
<p>Ruby doesn't have multiple inheritance. Ruby method lookup uses a linked listed, not a tree. This is the reason for iclasses, and why including module B in module A after A has been included in class C does not include B in C.</p>
<p>Note that I am not an expert on ruby internals, so if there are errors in the above description, hopefully a more knowledgeable person can correct me.</p> Ruby master - Bug #9573: descendants of a module don't gain its future ancestors, but descendants of a class, dohttps://redmine.ruby-lang.org/issues/9573?journal_id=457712014-03-13T21:29:08Zrits (First Last)
<ul></ul><p>Jeremy Evans wrote:</p>
<blockquote>
<p>Ruby doesn't have multiple inheritance. Ruby method lookup uses a linked listed, not a tree. This is the reason for iclasses, and why including module B in module A after A has been included in class C does not include B in C.</p>
</blockquote>
<p>Conceptually Ruby does have multiple inheritance, an object <code>is_a?</code>(all included modules).</p>
<p>Is MRI's iclass snapshotting an implementation detail? Can it theoretically be done differently (e.g. tree that you mentioned)</p> Ruby master - Bug #9573: descendants of a module don't gain its future ancestors, but descendants of a class, dohttps://redmine.ruby-lang.org/issues/9573?journal_id=470452014-06-05T06:16:16Zhsbt (Hiroshi SHIBATA)hsbt@ruby-lang.org
<ul></ul><p>ref. <a href="https://github.com/ruby/ruby/pull/549" class="external">https://github.com/ruby/ruby/pull/549</a></p> Ruby master - Bug #9573: descendants of a module don't gain its future ancestors, but descendants of a class, dohttps://redmine.ruby-lang.org/issues/9573?journal_id=836212020-01-04T05:43:58Zioquatix (Samuel Williams)samuel@oriontransfer.net
<ul><li><strong>Backport</strong> deleted (<del><i>1.9.3: UNKNOWN, 2.0.0: UNKNOWN, 2.1: UNKNOWN</i></del>)</li></ul><p>Is there a clean way to fix this issue?</p> Ruby master - Bug #9573: descendants of a module don't gain its future ancestors, but descendants of a class, dohttps://redmine.ruby-lang.org/issues/9573?journal_id=836232020-01-04T07:21:38Zioquatix (Samuel Williams)samuel@oriontransfer.net
<ul></ul><p>From <a class="user active user-mention" href="https://redmine.ruby-lang.org/users/1604">@jeremyevans0 (Jeremy Evans)</a>:</p>
<blockquote>
<p>Previously it wasn't possible because there wasn't a way to go from the module to all iclasses generated from it.<br>
I think module_subclasses in struct rb_subclass_entry may now contain the necessary pointers, but I'm not sure.<br>
Actually, looks like the subclasses entry may contain it (module_subclasses is used by iclasses, not modules). This appears to be a linked list of iclasses for the module.</p>
</blockquote> Ruby master - Bug #9573: descendants of a module don't gain its future ancestors, but descendants of a class, dohttps://redmine.ruby-lang.org/issues/9573?journal_id=836912020-01-07T16:44:22Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul><li><strong>File</strong> <a href="/attachments/8223">include-future-ancestors-9573.patch</a> <a class="icon-only icon-download" title="Download" href="/attachments/download/8223/include-future-ancestors-9573.patch">include-future-ancestors-9573.patch</a> added</li></ul><p>Attached is a patch that implements support for this for <code>Module#include</code>, but not <code>Module#prepend</code>. It passes <code>make check</code>. I'm not sure if we want to support this for <code>Module#include</code> but not <code>Module#prepend</code>, as it would make them inconsistent.</p>
<p><code>Module#include</code> support isn't too difficult to implement. Conceptually, the patch is similar to the pull request nobu was working on (<a href="https://github.com/ruby/ruby/pull/549" class="external">https://github.com/ruby/ruby/pull/549</a>). nobu's approach using <code>rb_class_foreach_subclass</code> is definitely simpler, but I'm not sure what the issues were with it that caused the pull request to be closed (I didn't see nobu's pull request until after working on my patch).</p>
<p>It is probably possible to support this for <code>Module#prepend</code>, but I believe it would at least require creating an origin module for all modules that are included/prepended to other modules/classes. I think that's a necessary condition, but not a sufficient one, as doing that by itself doesn't allow <code>Module#prepend</code> to work similarly.</p> Ruby master - Bug #9573: descendants of a module don't gain its future ancestors, but descendants of a class, dohttps://redmine.ruby-lang.org/issues/9573?journal_id=837062020-01-08T20:23:19Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul><li><strong>File</strong> <a href="/attachments/8224">prepend-future-ancestors-9573.patch</a> <a class="icon-only icon-download" title="Download" href="/attachments/download/8224/prepend-future-ancestors-9573.patch">prepend-future-ancestors-9573.patch</a> added</li></ul><p>Attached is a work-in-progress patch that includes similar support for <code>Module#prepend</code>. It does work in terms of <code>Module#prepend</code> affecting classes/modules that have already included the receiver, but it causes failures in the tests that would need to be fixed. Example:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Object</span> <span class="k">def</span> <span class="nf">foo</span><span class="p">;</span> <span class="p">[]</span> <span class="k">end</span> <span class="k">end</span>
<span class="k">module</span> <span class="nn">A</span> <span class="k">def</span> <span class="nf">foo</span><span class="p">;</span> <span class="p">[</span><span class="ss">:A</span><span class="p">]</span> <span class="o">+</span> <span class="k">super</span> <span class="k">end</span> <span class="k">end</span>
<span class="k">module</span> <span class="nn">B</span> <span class="k">def</span> <span class="nf">foo</span><span class="p">;</span> <span class="p">[</span><span class="ss">:B</span><span class="p">]</span> <span class="o">+</span> <span class="k">super</span> <span class="k">end</span> <span class="k">end</span>
<span class="k">module</span> <span class="nn">C</span> <span class="k">def</span> <span class="nf">foo</span><span class="p">;</span> <span class="p">[</span><span class="ss">:C</span><span class="p">]</span> <span class="o">+</span> <span class="k">super</span> <span class="k">end</span> <span class="k">end</span>
<span class="k">module</span> <span class="nn">D</span> <span class="k">def</span> <span class="nf">foo</span><span class="p">;</span> <span class="p">[</span><span class="ss">:D</span><span class="p">]</span> <span class="o">+</span> <span class="k">super</span> <span class="k">end</span> <span class="k">end</span>
<span class="k">module</span> <span class="nn">E</span>
<span class="kp">include</span> <span class="no">C</span>
<span class="n">prepend</span> <span class="no">D</span>
<span class="k">def</span> <span class="nf">foo</span><span class="p">;</span> <span class="p">[</span><span class="ss">:E</span><span class="p">]</span> <span class="o">+</span> <span class="k">super</span> <span class="k">end</span>
<span class="k">end</span>
<span class="k">module</span> <span class="nn">Enumerable</span> <span class="k">def</span> <span class="nf">foo</span><span class="p">;</span> <span class="p">[</span><span class="ss">:Enumerable</span><span class="p">]</span> <span class="o">+</span> <span class="k">super</span> <span class="k">end</span>
<span class="k">end</span>
<span class="no">Enumerable</span><span class="p">.</span><span class="nf">include</span> <span class="no">A</span>
<span class="no">Enumerable</span><span class="p">.</span><span class="nf">prepend</span> <span class="no">B</span>
<span class="no">Enumerable</span><span class="p">.</span><span class="nf">include</span> <span class="no">E</span>
<span class="nb">p</span> <span class="p">[].</span><span class="nf">foo</span>
<span class="nb">p</span><span class="p">({}.</span><span class="nf">foo</span><span class="p">)</span>
</code></pre>
<p>Output:</p>
<pre><code>[:B, :Enumerable, :D, :E, :C, :A]
[:B, :Enumerable, :D, :E, :C, :A]
</code></pre>
<p>This does require creating origin iclasses for all modules that are included or prepended to other modules. It changes the origin pointer handling for iclasses such that the iclass origin pointer points not to the module origin but to the iclass origin. Due to the way module inclusion works, the iclass origin is not created at the point the iclass is created, so we need to keep a record of the created iclass, and when we come across the module origin and create the iclass origin, we set the origin for the iclass to the iclass origin.</p>
<p>Before doing more work in this area to attempt to fix the test failures, we should decide if we want this behavior and whether the necessary tradeoff of doubling the number of iclasses is worth it. Here are a few of the 43 test-all failures:</p>
<pre><code> 1) Failure:
Complex_Test#test_respond [/home/jeremy/tmp/ruby/test/ruby/test_complex.rb:934]:
Complex#clamp.
Expected (1+1i) to not respond to clamp.
2) Failure:
TestModule#test_override_optmethod_after_prepend [/home/jeremy/tmp/ruby/test/ruby/test_module.rb:1990]:
<a href="/issues/11836">[ruby-core:72226]</a> [Bug #11836].
<(1/2)> expected but was
<0>.
...
42) Error:
TestAlias#test_super_in_aliased_module_method:
NoMethodError: super: no superclass method `foo' for #<TestAlias::SuperInAliasedModuleMethod::Derived:0x000006e8b02d3d78>
Did you mean? for
/home/jeremy/tmp/ruby/test/ruby/test_alias.rb:96:in `foo'
/home/jeremy/tmp/ruby/test/ruby/test_alias.rb:115:in `test_super_in_aliased_module_method'
43) Error:
TestRefinement#test_refine_module:
NoMethodError: super: no superclass method `bar' for #<TestRefinement::RefineModule::C:0x000006e8afad0018>
Did you mean? baz
/home/jeremy/tmp/ruby/test/ruby/test_refinement.rb:453:in `bar'
/home/jeremy/tmp/ruby/test/ruby/test_refinement.rb:469:in `call_bar'
/home/jeremy/tmp/ruby/test/ruby/test_refinement.rb:479:in `test_refine_module'
</code></pre> Ruby master - Bug #9573: descendants of a module don't gain its future ancestors, but descendants of a class, dohttps://redmine.ruby-lang.org/issues/9573?journal_id=844062020-02-27T08:23:33Zmatz (Yukihiro Matsumoto)matz@ruby.or.jp
<ul></ul><p>The patch for <code>include</code> looks OK to me. To ensure there are no unseen compatibility issues, I'd like to experiment with it during the 2.8 development cycle. I am not yet sure how <code>prepend</code> should work here. I need to think about it more deeply. Keep it as it is for <code>prepend</code> for the moment.</p>
<p>Matz.</p> Ruby master - Bug #9573: descendants of a module don't gain its future ancestors, but descendants of a class, dohttps://redmine.ruby-lang.org/issues/9573?journal_id=844152020-02-27T19:03:32Zjeremyevans (Jeremy Evans)code@jeremyevans.net
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Closed</i></li></ul><p>Applied in changeset <a class="changeset" title="Make Module#include affect the iclasses of the module When calling Module#include, if the receiv..." href="https://redmine.ruby-lang.org/projects/ruby-master/repository/git/revisions/3556a834a2847e52162d1d3302d4c64390df1694">git|3556a834a2847e52162d1d3302d4c64390df1694</a>.</p>
<hr>
<p>Make Module#include affect the iclasses of the module</p>
<p>When calling Module#include, if the receiver is a module,<br>
walk the subclasses list and include the argument module in each<br>
iclass.</p>
<p>This does not affect Module#prepend, as fixing that is significantly<br>
more involved.</p>
<p>Fixes [Bug <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: descendants of a module don't gain its future ancestors, but descendants of a class, do (Closed)" href="https://redmine.ruby-lang.org/issues/9573">#9573</a>]</p> Ruby master - Bug #9573: descendants of a module don't gain its future ancestors, but descendants of a class, dohttps://redmine.ruby-lang.org/issues/9573?journal_id=844162020-02-27T19:08:42Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul><li><strong>Status</strong> changed from <i>Closed</i> to <i>Open</i></li></ul> Ruby master - Bug #9573: descendants of a module don't gain its future ancestors, but descendants of a class, dohttps://redmine.ruby-lang.org/issues/9573?journal_id=851542020-04-17T03:38:17Zioquatix (Samuel Williams)samuel@oriontransfer.net
<ul></ul><p><a class="user active user-mention" href="https://redmine.ruby-lang.org/users/1604">@jeremyevans0 (Jeremy Evans)</a> thanks so much for fixing this at least in the #include case.</p> Ruby master - Bug #9573: descendants of a module don't gain its future ancestors, but descendants of a class, dohttps://redmine.ruby-lang.org/issues/9573?journal_id=859702020-06-03T19:19:15Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul></ul><p>With my recent changes to fix the bugs in the object model related to prepend and refinements, adding support for Module#prepend is now straightforward and breaks no tests or specs. I've added a pull request for it: <a href="https://github.com/ruby/ruby/pull/3181" class="external">https://github.com/ruby/ruby/pull/3181</a></p> Ruby master - Bug #9573: descendants of a module don't gain its future ancestors, but descendants of a class, dohttps://redmine.ruby-lang.org/issues/9573?journal_id=862142020-06-18T05:00:31Zmatz (Yukihiro Matsumoto)matz@ruby.or.jp
<ul></ul><p>Updating <code>prepend</code> looks OK to me now. Let's try it.</p>
<p>Matz.</p> Ruby master - Bug #9573: descendants of a module don't gain its future ancestors, but descendants of a class, dohttps://redmine.ruby-lang.org/issues/9573?journal_id=862372020-06-18T15:18:52Zjeremyevans (Jeremy Evans)code@jeremyevans.net
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Closed</i></li></ul><p>Applied in changeset <a class="changeset" title="Make Module#prepend affect the iclasses of the module 3556a834a2847e52162d1d3302d4c64390df1694 a..." href="https://redmine.ruby-lang.org/projects/ruby-master/repository/git/revisions/41582d5866ae34c57094f70f95c3d31f4a1fa4ff">git|41582d5866ae34c57094f70f95c3d31f4a1fa4ff</a>.</p>
<hr>
<p>Make Module#prepend affect the iclasses of the module</p>
<p>3556a834a2847e52162d1d3302d4c64390df1694 added support for<br>
Module#include to affect the iclasses of the module. It didn't add<br>
support for Module#prepend because there were bugs in the object model<br>
and GC at the time that prevented it. Those problems have been<br>
addressed in ad729a1d11c6c57efd2e92803b4e937db0f75252 and<br>
98286e9850936e27e8ae5e4f20858cc9c13d2dde, and now adding support for<br>
it is straightforward and does not break any tests or specs.</p>
<p>Fixes [Bug <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: descendants of a module don't gain its future ancestors, but descendants of a class, do (Closed)" href="https://redmine.ruby-lang.org/issues/9573">#9573</a>]</p> Ruby master - Bug #9573: descendants of a module don't gain its future ancestors, but descendants of a class, dohttps://redmine.ruby-lang.org/issues/9573?journal_id=862832020-06-21T06:57:40Znaruse (Yui NARUSE)naruse@airemix.jp
<ul><li><strong>Related to</strong> <i><a class="issue tracker-1 status-8 priority-4 priority-default closed" href="/issues/16973">Bug #16973</a>: Rails Active Support unit test fails since 41582d5866</i> added</li></ul>