From: Trans Date: 2007-03-16T07:20:01+09:00 Subject: Re: General Ruby OOP Question - using inheritance or include for shared attributes On Mar 15, 11:25 am, james.d.mast...@gmail.com wrote: > On Mar 15, 12:11 am, "Trans" wrote: > > > module X; def self.x; "x"; end; end > > class Y; include X; end > > Y.x #=> error > > > IMHO It's unfortunate that this is the case --or at least that there's > > not a method other than #include that can do it. I guess it's because > > I wrote annotations, which turned out to be very tricky b/c of this. > > In the case of pulling in module methods as class (singleton) methods, > you can use extend instead of include. Your second example rewritten > with "extend" would work: > > module X; def x; "x"; end; end > class Y; extend X; end > Y.x #=> "x" > > Unfortunately, I'm fairly sure that would require separate modules for > class methods (through extend) and instance methods (through include). Have a look at module/class_extension in Facets. This sophisticated code was developed by Daniel Schierbeck with the help of a number of people including myself, Nobu Nakada, Ulysses and Matz. 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_extension 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 T.