[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: Include and Extend Again....

Jano Svitok

11/6/2006 3:19:00 PM

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

1 Answer

Jano Svitok

11/6/2006 3:37:00 PM

0

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 ;-)
>
>
> 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.

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.