2006-08-26

The Persnickety Order of Self Serving Modules

This one caught me off guard.


irb(main):001:0> module M
orb(main):002:1> def x; "x"; end
orb(main):003:1> end
=> nil
orb(main):005:0> module Q
orb(main):006:1> extend self
orb(main):007:1> include M
orb(main):008:1> end
=> Q
orb(main):009:0> Q.x
NoMethodError: undefined method `x' for Q:Module
from (orb):9
from :0


Why isn't the included #x coming along for the ride in the self extension of Q? This kind of dyanmicism is vital when dynamically loading behaviors. And so I suspect it must do with the dread Dynamic Module Inclusion Problem? And it would appear that I am right:


orb(main):012:0> module M
orb(main):013:1> def x; "x"; end
orb(main):014:1> end
=> nil
orb(main):015:0> module Q
orb(main):016:1> include M
orb(main):017:1> extend self
orb(main):018:1> end
=> Q
orb(main):019:0> Q.x
=> "x"


Yes, another of the edge cases. But the preponderance weighs heavy on the Coding Spirit. The Dynamic Module Inclusion Problem is getting old.

5 comments:

Pit said...

Tom, if you want an object to respond to the methods of a module, you have to *extend* the object with the module. Replace "include" with "extend" and your code should work.

lopex said...

But there is a slightly different issue:

http://eigenclass.org/hiki.rb?cmd=view&p=The+double+inclusion+problem&key=limitation

Pit said...

lopex: yes, for many years I've been aware of the problem you mention, but couldn't find a solution yet. Tom's problem though is a different one (at least it seems to me).

a different tom said...

Howdy. Did your implementation of e4x for ruby ever go anywhere? It's a great idea.

tea42 said...

Hi Pit. Yea my example has no context, so I can see what your thinking. But I actually do want to use 'include'. I'm trying to show that the 'extend self' should have pulled in the inculded methods to class-level access --well, it would if it weren't for the dynamic inclusion issue. That's way it actually works in one order but not the other. At least that's what I think is going on here.