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

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.

···

from :0

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

···

On 6/23/07, Trans <transfire@gmail.com> wrote:

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?

--
Rick DeNatale

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

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?

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

···

On 6/23/07, Trans <transfire@gmail.com> wrote:

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

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.

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 6/23/07, Trans <transfire@gmail.com> wrote:
--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw

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, 4:37 am, "Pit Capitain" <pit.capit...@gmail.com> wrote:

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

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

···

2007/6/24, Trans <transfire@gmail.com>:

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.

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.

···

On Jun 24, 8:01 am, "Pit Capitain" <pit.capit...@gmail.com> wrote:

2007/6/24, Trans <transf...@gmail.com>:

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