Forum: Ruby include module in module

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Ittay D. (Guest)
on 2008-12-08 09:13
(Received via mailing list)
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 D. (Guest)
on 2008-12-08 09:55
(Received via mailing list)
Ittay D. wrote:

>
> class C2
>
> module M
> 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
Robert K. (Guest)
on 2008-12-08 14:10
(Received via mailing list)
2008/12/8 Ittay D. <removed_email_address@domain.invalid>:
>  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?

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
This topic is locked and can not be replied to.