Include and Extend Again

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 Object
     include A
  end

  require 'test/unit'

  class MyModuleTest < Test::Unit::TestCase
    def test_object_should_have_the_a_method_as_class_method
      assert Object.respond_to?( :a )
    end

    def test_object_should_not_have_the_a_method_as_instance_method
      assert !Object.new.respond_to?( :a )
    end

    def test_object_should_have_the_b_method_as_instance_method
      assert Object.new.respond_to?( :b )
    end

    def test_object_should_not_have_the_b_method_as_class_method
      assert !Object.respond_to?( :b )
    end
  end

  require 'test/unit/ui/console/testrunner'
  Test::Unit::UI::Console::TestRunner.run(MyModuleTest)

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 :wink:

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

···

On 11/6/06, Daniel N <has.sox@gmail.com> wrote:

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 :wink:

Well that works a treat. I changed the class definition to
class Thing
  include A
end

and it worked great. The incestuous relationship between Object and Class
has not really raised it's head as a problem for me before so it didn't even
enter my mind.
Thanx for pointing it out.

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

Thanx for that. I had a feeling that might be the case. With the other
error I was just unsure.

module A

...
  include InstanceMethods
end

Thanx very much for your reply.

Daniel

···

On 11/7/06, Jan Svitok <jan.svitok@gmail.com> wrote:

Just to be clear:

IMO your problem is the first issue - the Object and Class
relationship. The second issue is just a cosmetic change, and has no
impact on whether it works or not. The difference is a) aesthetical b)
how many time the InstanceMethod module is included - either into any
object/class that includes A or just once into A and *through* it into
other objects.

···

On 11/6/06, Daniel N <has.sox@gmail.com> wrote:

On 11/7/06, Jan Svitok <jan.svitok@gmail.com> wrote:
>
> 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 :wink:

Well that works a treat. I changed the class definition to
class Thing
  include A
end

and it worked great. The incestuous relationship between Object and Class
has not really raised it's head as a problem for me before so it didn't even
enter my mind.
Thanx for pointing it out.

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

Thanx for that. I had a feeling that might be the case. With the other
error I was just unsure.

module A
> ...
> include InstanceMethods
> end
>
> Thanx very much for your reply.