From: Jan Svitok Date: 2006-11-07T00:18:41+09:00 Subject: Re: Include and Extend Again.... On 11/6/06, Daniel N wrote: > Hi all, > > I must be really thick with this because I cannot get my class to behave. > > What I want to do is > > class AClass > include AModule > end > > and have that module mixin both instance and class methods. I've seen this > done, but obviously I don't understand what's really going on because I > can't make it happen. I know this has been discussed on the list before as > well. I've reviewed that as well. I fell really thick with this one. It's > just not going in. > > Here's what I've tried (don't worry it's short). I put this into a single > file and just run it. Any pointers to the source of my misunderstanding > would be great. > > Thanx > > module A > > def self.included(base) > base.extend ClassMethods > base.send( :include, InstanceMethods ) > end > > module InstanceMethods > def b > puts "I'm an instance method" > end > end > > module ClassMethods > def a > puts "I'm a class method" > end > end > > end > class AClass > include A > end > > > require 'test/unit' > > class MyModuleTest < Test::Unit::TestCase > def test_object_should_have_the_a_method_as_class_method assert AClass.respond_to?( :a ) > end > > def test_object_should_not_have_the_a_method_as_instance_method assert !AClass.new.respond_to?( :a ) > end > > def test_object_should_have_the_b_method_as_instance_method assert AClass.new.respond_to?( :b ) > end > > def test_object_should_not_have_the_b_method_as_class_method assert !AClass.respond_to?( :b ) > end > end > > require 'test/unit/ui/console/testrunner' > Test::Unit::UI::Console::TestRunner.run(MyModuleTest) Your problem is, that Class.is_a? Object i.e. object Class is an instance of class Object. Therefore all instance methods of Object are class methods (or vice versa, I'm getting lost a bit ;-) Second issue: your instance methods: you can simply put them in main A module (as rails does), or add include InstanceMethods line at the end of A module definition and thus you can leave out the base.send(:include) line module A ... include InstanceMethods end