I have been having trouble today with a module include in a Rails app.
The module file sits in the /lib folder.
My problem, I worked out (which I have noticed before) is that I cannot
seem to access defined class methods in the module via the including
class. It seems that only instance methods are available. Let me
my_class = MyClass.new
test1 = MyClass.test #=> gives an NoMethodError
test2 = my_class.test #=> works
Is there something I am missing here? Please note I just wrote this code
quickly to show the idea, have not tested!
Its not essential but seems a bit silly that I need to use an instance
method in a situation when a class method would be much neater.
Any pointers much appreciated!
If you have a spare six months, you can look through the previous
discussions of this topic on this list
Basically, the module and the class that includes it are independent
agents, when it comes to their own singleton/class methods. The
include operation is for the benefit of the objects that already
consult the class for methods: it adds the module to the method lookup
path of those objects. The class object itself is unaffected.
You can intercept the include event, though, and manipulate the lookup
path of the class object itself. A very common pattern is:
puts "Instance method"
puts "Class method"
C.new.x # Instance method
C.y # Class method
The idea here is to extend (i.e., do a per-object include) the class
object itself with a specialized module, M::ClassMethods, at the same
time that the module M is included in the class.
The name "ClassMethods", of course, is arbitrary; the methods defined
in that module are instance methods of the M::ClassMethods module.
They only become "class methods" by virtue of the extend operation.
I know it probably seems like a lot of work for something that you
might think should be automatic, but it's actually good that it isn't
automatic, because that would remove the ability to keep the singleton
(class) methods of a given module and a given class separate. This
way, with the out-of-the-box behavior being the more basic, there's
nothing you can't do.
On Fri, 20 Feb 2009, Adam Wilson wrote:
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Coming in 2009: The Well-Grounded Rubyist (http://manning.com/black2)
Ruby Training Atlanta! April 1-3, http://www.entp.com/training/atlanta09