On 11/6/06, Daniel N <has.sox / gmail.com> 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