Can't include a module in Enumerable?

irb(main):002:1> module Z
irb(main):003:1> def x; “x”; end
irb(main):004:1> end
=> nil
irb(main):005:0> module Enumerable
irb(main):006:1> include Z
irb(main):007:1> end
=> Enumerable
irb(main):008:0> a = [1,2,3,4,5]
=> [1, 2, 3, 4, 5]
irb(main):009:0> a.x
NoMethodError: undefined method `x’ for [1, 2, 3, 4, 5]:Array
from (irb):9
from :0

Is the Double Inclusion Problem worse than I realized? I thought the
above would be okay b/c ‘a’ is instantiated after the inclusion
(which is why I’ve often called it the Dynamic Inclusion Problem).
What gives?

T.

On 6/23/07, Trans [email protected] wrote:

irb(main):009:0> a.x
NoMethodError: undefined method `x’ for [1, 2, 3, 4, 5]:Array
from (irb):9
from :0

Is the Double Inclusion Problem worse than I realized? I thought the
above would be okay b/c ‘a’ is instantiated after the inclusion
(which is why I’ve often called it the Dynamic Inclusion Problem).
What gives?

It’s not the instance, it’s the class Array, and that existed (and
included Enumerable) before you changed Enumerable.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

On 6/23/07, Trans [email protected] wrote:

irb(main):009:0> a.x
NoMethodError: undefined method `x’ for [1, 2, 3, 4, 5]:Array
from (irb):9
from :0

Is the Double Inclusion Problem worse than I realized? I thought the
above would be okay b/c ‘a’ is instantiated after the inclusion
(which is why I’ve often called it the Dynamic Inclusion Problem).
What gives?

Rick answered this, but maybe this is a solution for what you’re trying
to do:

module ZEnumerable
include Enumerable
def x; “x”; end
end

class B
include ZEnumerable

?> def each

[1,2,3].each { |e| yield(e) }

end
end

class Array
include ZEnumerable
end
=> Array
[1,2,3].x
=> “x”
B.new.map { |e| e + 1 }
=> [2, 3, 4]
B.new.x
=> “x”

Yeah, you’d need to go remix existing enumerable classes, but it keeps
you from having to do the additional include for new objects

Tom, here’s something to experiment with. I haven’t tested it
extensively:

class Module
alias :old_include :include
def include other
old_include other
if self.class == Module
this = self
ObjectSpace.each_object Module do |mod|
mod.module_eval do include this end if mod < self
end
end
end
end

module Z
def x; “x”; end
end

module Enumerable
include Z
end

a = [1,2,3,4,5]
p a.x # => “x”

Regards,
Pit

On 6/23/07, Trans [email protected] wrote:

irb(main):009:0> a.x

Just reinclude Enumerable, well that seems to be the simplest way to
achieve what you wanted:

510/10 > irb
irb(main):001:0> module A; def x; 42 end end
=> nil
irb(main):002:0> module Enumerable; include A end
=> Enumerable
irb(main):003:0> class Array; include Enumerable end
=> Array
irb(main):004:0> [].x
=> 42

And yes it works outside irb too.

Robert

On Jun 24, 4:37 am, “Pit C.” [email protected] wrote:

    end

end

a = [1,2,3,4,5]
p a.x # => “x”

Regards,
Pit

Pit Smack Down! You go and solve the Double Inclusion Problem just
like that!?

There must be a large issue. Why wouldn’t Matz have already pursued
this? Granted, I see a little inefficiency, but nothing an Observer
pattern couldn’t mitigate. What say you?

I’m Speechless.

T.

On Jun 24, 8:01 am, “Pit C.” [email protected] wrote:

Tom, thanks for the kind words, but it’s really not so hard to find
just one solution to this problem. I can’t speak for Matz, but I think
he’s looking for a more efficient solution that doesn’t require a lot
of bookkeeping.

Okay, I’m being a bit hyperbolic. But you deserve it anyway. I was
surprised to see a solution thrown up in a few lines of code. The
impression I had developed over previous discourse was such a thing
was not readily possible. Of course, now it seems obvious. I knew we
could just re-include the module, I just never put two and two
together.

T.

2007/6/24, Trans [email protected]:

Pit Smack Down! You go and solve the Double Inclusion Problem just
like that!?

There must be a large issue. Why wouldn’t Matz have already pursued
this? Granted, I see a little inefficiency, but nothing an Observer
pattern couldn’t mitigate. What say you?

I’m Speechless.

Tom, thanks for the kind words, but it’s really not so hard to find
just one solution to this problem. I can’t speak for Matz, but I think
he’s looking for a more efficient solution that doesn’t require a lot
of bookkeeping.

Regards,
Pit