On Sat, Dec 5, 2009 at 12:37 AM, Mike P. [email protected]
wrote:
I would like to include a module into a ‘static’ class - such that all
the modules methods are class methods.
One basic way to do this is to have the class extend the module:
irb(main):017:0> module Z
irb(main):018:1> def test; “testZ”; end
irb(main):019:1> end
=> nil
irb(main):020:0> class C
irb(main):021:1> extend Z
irb(main):022:1> end
=> C
irb(main):023:0> C.test
=> “testZ”
def mb
self.class.cee
This is wrong. self.class is Class, and the Class class doesn’t have a
method “cee”.
end
module ClassMethods
attr_writer :cee
def cee
puts “CCCCCCCCCCCCC”
end
end
end
I think you are confusing this usage. The name ClassMethods is a
convention used to denote a set of methods that will be added to the
class as class methods when you include this module. This is usually
done as:
module Test
module ClassMethods
def test; “test”; end
end
def self.included mod
mod.extend ClassMethods
end
end
If you simply want a method defined in the singleton class of your
module do:
module Basic
def self.cee
“CCCCCCC”
end
end
If you want to call it from a method of the module:
module Basic
def mb
Basic.cee
end
def self.cee
“CCCCC”
end
end
If you then want mb to be a class method of the classes you choose,
you can use extend instead of include:
irb(main):045:0> module Basic
irb(main):046:1> def mb
irb(main):047:2> Basic.cee
irb(main):048:2> end
irb(main):049:1> def self.cee
irb(main):050:2> “CCCCCCCCCCCCC”
irb(main):051:2> end
irb(main):052:1> end
=> nil
irb(main):053:0> class YY
irb(main):054:1> extend Basic
irb(main):055:1> end
=> YY
irb(main):056:0> YY.mb
=> “CCCCCCCCCCCCC”
I think my understanding of modules and using extend (or include) is
faulty or at least doesnt cover the subtleties of when a modle uses
“self.class” and its included in another class, then what becomes of
self.class in this case??
You can ask Ruby 
irb(main):036:0> module Basic
irb(main):037:1> def mb
irb(main):038:2> puts self
irb(main):039:2> end
irb(main):040:1> end
=> nil
irb(main):041:0> class XX
irb(main):042:1> extend Basic
irb(main):043:1> end
=> XX
irb(main):044:0> XX.mb
XX
So, how it works is that when a class extends a module, the methods
get added to the singleton class of the class. This means that the
method is now in the lookup path of the class methods. But (and this
is the same with the normal inheritance) self inside those methods is
still the original object that received the method call, so in this
case the class XX. Another example:
irb(main):058:0> class Class
irb(main):059:1> def test_class; puts self; end
irb(main):060:1> end
=> nil
irb(main):061:0> XX.test_class
XX
This is with simple inheritance (XX inherits from Class). With
extended modules it’s the same, as shown above.
Basically:
1.- extend includes the methods in that module to the singleton class
of the receiving object.
2.- classes are objects
3.- so when a class extends a module, the module instance methods (is
that the correct way to refer to those?) get added to the singleton
class of the class (commonly known as class methods).
This stuff is tricky, and I don’t know if I explained myself very
well, so please ask if there’s something not clear enough.
Hope this helps,
Jesus.