Issue #7240 has been updated by apotonick (Nick Sutterer).


Interesting points, mates. I don't know about the method tables so all I can do is summarizing what we came up with so far.

h2. 1. Explicitely define inheritable class methods.

<code>module M
inclusive/inheritable
  def self.i_will_be_inherited
</code>

When then included, this method will be inherited. This would solve most problems as 
<pre>
inclusive/inheritable
  def self.included(..)
</PRE>
would mean that the #included method itself can be made inheritable!


h2. Explicitely inherit when including

If we had a new #include! method we inherit all (?) class methods.

<pre>module M
  def self.m
end

module U
  include! M

  # class method #m is now around.
end
</pre>

Problem here is: The *user* has to know about whether or not to import class methods which is not what I want as a gem developer (I don't want my gem users to know whether they should use #include or #include!). Also, no fine-tuning since _all_ class methods are imported.


----------------------------------------
Feature #7240: Inheritable #included/#extended Hooks For Modules
https://bugs.ruby-lang.org/issues/7240#change-32084

Author: apotonick (Nick Sutterer)
Status: Open
Priority: Normal
Assignee: 
Category: 
Target version: 


An inheritable hook mechanism for modules would be a great way for module/gem authors to simplify their implementations.


The Problem
-----------

Let's say I have the following module.

  module A
    def self.included(base)
      # add class methods to base
    end
  end

So, A is overriding the #included hook to add class methods to base.

module B
  include A

  # class methods from A are here.
end

Since B is including A, A's #included method is invoked and A's class methods will be copied to B.

module C
  include B

  # class methods from B are lost.
end

When including B into C, B's #included is invoked and A's #included is lost. In our example, this means no class methods from A are in C.


Proposal
--------

It would be cool if #included/#extended in a module could be inherited to including descendants. I wrote a small gem "uber" that does this kind of stuff with a simple recursion. Roughly, it works like this.

  module A
    extend InheritableIncluded # "execute my #included everytime me or my descendents are included."

    def self.included(base)
      # add class methods to base
    end
  end

Now, A's #included is invoked every time it or a descending module is included. In our example, class methods from A would be around in C.

When discussing this with Matz we agreed that this might be really useful in Ruby itself. I'm just not sure how to mark inheritable hooks.


-- 
http://bugs.ruby-lang.org/