From: Rick DeNatale Date: 2009-12-05T11:47:48+09:00 Subject: Re: Use of extend from within a Class On Fri, Dec 4, 2009 at 6:37 PM, Mike Papper wrote: > I would like to include a module into a 'static' class - such that all > the modules methods are class methods. The problem is that code in the > module that uses "self.class.XYZ' breaks and when this code is included, > ruby cannot find the XYZ method. > > Here is an example: > > module Basic >  def methoda >    puts "AAAAAAAAAAA" >  end > >  def mb >    self.class.cee >  end > >  module ClassMethods >    attr_writer :cee > >    def cee >      puts "CCCCCCCCCCCCC" >    end >  end > end > class Use >  extend Basic Okay, at this point in the class definition self == Use and extend Basic mixes the Basic module into the singleton class of Use, so all of the methods of Basic (i.e. mb and methoda) are now CLASS methods of Use There is no actual usage of Basic::ClassMethods >  def self.z This is a class method of Use (because of def self.z) inside this method self is also the class object Use >    mb >  end > end > > If I do the following: >  Use.z > > I get this error: > NoMethodError: undefined method `cee' for Class:Class >        from (irb):100:in `mb' >        from (irb):116:in `z' >        from (irb):119 so what happened. in Basic#mb we have def mb self.class.cee end and self is still the class object Use, but Use.class is class, which is one issue. Even if the mb method had self.cee, Use doesn't have cee as a class method because although Basic::ClassMethods was defined, it was never referenced. As Jesus pointed out, you appeared to be confused with the way Rails, and lots of other ruby code causes modules to add both instance and class methods to classes which include them. The normal pattern is module SomeModule # define any instance methods here module ClassMethods # define any class methods here end # and here is the crucial step this gets called when some class # includes the module def self.included(some_class) some_class.extend(ClassMethods) end end So if you want to make a module which adds only class methods either 1) define the module 'normally' and in the class which wants the methods as class methods class Foo extend MyGreatModuleOfClassMethods end or 2) Use the pattern above, leave the instance methods out, and put all of the methods in the inner ClassMethods module (actually the name of this module is irrelevant except for clarity. then in the using class class Foo include MyGreatModuleWhichOnlyHasClassMethodsRightNow end HTH -- Rick DeNatale Blog: http://talklikeaduck.denhaven2.com/ Twitter: http://twitter.com/RickDeNatale WWR: http://www.workingwithrails.com/person/9021-rick-denatale LinkedIn: http://www.linkedin.com/in/rickdenatale