Hi-- Vincent Fourmond wrote: > Hello ! > > I have a rather tortured architecture where several classes should > share code for some class methods and for some instance methods. To fix > the ideas, I need that some class I define have: > > def ThisClass.desc > return @desc > end > > def desc > return self.class.desc > end > > To do that, I define two modules > > module BaseInclude > def desc > return self.class.desc > end > end > > module BaseExtend > def desc > return @desc > end > end > > and I include them with > > class ThisClass > include BaseInclude > extend BaseExtend > end > > That works perfectly fine. My question, then, is : is there a simpler > way ? I can't afford to have a shared ancestor for these classes. > > Thanks ! Not too long ago this was discussed with a length with Matz. The result was #class_extension. module Base def desc return self.class.desc end class_extension do def desc return @desc end end end class ThisClass include Base end An excellent pure Ruby implementation of this was developed by Daniel Schierbeck, It can be found it the Facets project (facets.rubyforge.org). To use: require 'facet/module/class_extension'. For convenience the code follows. It remains to be seen if Matz ultimately goes with this approach in Ruby 2.0. But as of yet I guess one could say it the most "official" technique available. (Not to say that others are prefectly valid of course) T. class Module alias_method :append_features_without_class_extension, :append_features # = class_extension # # Normally when including modules, class/module methods are not # extended. To achieve this behavior requires some clever # Ruby Karate. Instead class_extension provides an easy to use # and clean solution. Simply place the extending class methods # in a block of the special module method #class_extension. # # module Mix # def inst_meth # puts 'inst_meth' # end # # class_methods do # def class_meth # "Class Method!" # end # end # end # # class X # include Mix # end # # X.class_meth #=> "Class Method!" # def class_extension(&block) @class_extension ||= Module.new do def self.append_features(mod) append_features_without_class_extension(mod) end end @class_extension.module_eval(&block) if block_given? @class_extension end private :class_extension def append_features(mod) append_features_without_class_extension(mod) mod.extend(class_extension) if mod.instance_of? Module mod.__send__(:class_extension).__send__(:include, class_extension) end end end class Class undef_method :class_extension end