include module in module

Discussion in 'Ruby' started by Ittay Dror, Dec 8, 2008.

  1. Ittay Dror

    Ittay Dror Guest

    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, Dec 8, 2008
    #1
    1. Advertisements

  2. Ittay Dror

    Ittay Dror Guest

    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
     
    Ittay Dror, Dec 8, 2008
    #2
    1. Advertisements

  3. 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
     
    Robert Klemme, Dec 8, 2008
    #3
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.