From: "alexeymuranov (Alexey Muranov)" Date: 2012-10-31T07:35:10+09:00 Subject: [ruby-core:48632] [ruby-trunk - Feature #7240] Inheritable #included/#extended Hooks For Modules Issue #7240 has been updated by alexeymuranov (Alexey Muranov). In my opinion, the most common use case for the `included` hook in modules is adding class methods. However, to me this looks hackish -- hard to follow and understand. I would have preferred if there was a way to define both instance-level and class-level behavior in a module and include both at once : module M def foo # ... end def base.bar # here a fictional method Module#base is called # ... end end class C meta_include M end a = C.new a.foo C.bar After all, ordinary objects have no method table, classes have one method table, why not to allow modules to have 2 method tables? Talking about method tables, maybe if objects were allowed to have one, there would be no need for metaclasses? (Then classes would have 2 method tables, modules would have 3, and in fact methods and method tables could be regarded as different kinds of attributes.) By the way, i think that from the point of view of English the method name `included` is not consistent with the method name `extended` (the *module* is included, but the *base* is extended). ---------------------------------------- Feature #7240: Inheritable #included/#extended Hooks For Modules https://bugs.ruby-lang.org/issues/7240#change-32046 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/