Include module in module

Hi,

I have a situation like this:

module M

   ....

end

class C1

   include M

   ...

end

class C2

   include M

   ...

end

Now I want to add methods to C1 and C2 and whatever other class includes M.

My first approach was:

module S

   ....

end

module M

   include S

end

But this doesn't work (meaning whatever methods I have in S are undefined for instances of C1, C2).

So, how can I do that?

Thanks,

Ittay

···

--
--
Ittay Dror <ittay.dror@gmail.com>

Ittay Dror wrote:

Hi,

I have a situation like this:

module M

  ....

end

class C1

  include M

  ...

end

class C2

  include M

  ...

end

Now I want to add methods to C1 and C2 and whatever other class includes M.

My first approach was:

module S

  ....

end

module M

  include S

end

But this doesn't work (meaning whatever methods I have in S are undefined for instances of C1, C2).

So, how can I do that?

I think I solved it:
module S
   def self.included(other)
      methods = instance_methods(false)
      other.module_eval do
         methods.each do |name|
            name = name.to_sym
            base.send :define_method, name, instance_method(name)
          end
      end
   end
end

Ittay

···

Thanks,

Ittay

--
--
Ittay Dror <ittay.dror@gmail.com>

There are at least these two possible approaches

1. add methods to M
2. create another module S and include it in all classes inheriting M
2b. same as 2 but insert S only in the inheritance hierarchy of
classes that directly include M

#!/bin/env ruby

module M
  def m
    "Mmmmh!"
  end
end

class A
  include M
end

class B
  include M
end

# approach 1

module M
  def late
    "late"
  end
end

puts A.new.late, B.new.late

# approach 2

module S
  def even_later
    "even_later"
  end
end

ObjectSpace.each_object(Class) do |cl|
  if cl.ancestors.include?(M) && !cl.ancestors.include?(S)
    cl.class_eval { include S }
  end
end

puts A.new.even_later, B.new.even_later

# approach 2b

module S2
  def x
    "X"
  end
end

ObjectSpace.each_object(Class) do |cl|
  a = cl.ancestors
  i = a.index(M)
  if i && a[1...i].all? {|c| not Class === c}
    cl.class_eval { include S2 }
  end
end

puts A.new.x, B.new.x

Cheers

robert

···

2008/12/8 Ittay Dror <ittay.dror@gmail.com>:

I have a situation like this:

module M
end

class C1
include M
end

class C2
include M
end

Now I want to add methods to C1 and C2 and whatever other class includes M.

So, how can I do that?

--
remember.guy do |as, often| as.you_can - without end