Ruby - 从包含另一个模块的模块中获取类和实例方法?

时间:2014-03-14 08:48:41

标签: ruby metaprogramming

对标题表示道歉,欢迎提出更明确的建议。

我创建了一个模块(我们将用M来表示这个),当include d在类中时,会导致它获取新的类方法和实例方法(如果我的术语是道歉的话)是不正确的)。这是通过= class F实现的,包括下面代码中的A::ModuleInstanceMethods模块。

既然我已经这样做了,我正在尝试创建一个新模块(我们称之为新模块M'),其中包含模块M,以便在{{1}时如果包含在类中,则类应根据类M'获取适当的类和实例方法。这是我被卡住的地方。此类的示例在下面的代码中为F

我还希望G模块include(模块M''将包含M'')的类具有相同的功能。一个例子是下面代码中的类M'。对于包含H(其本身包括M''')的类,M''(其本身包括M'''')等的类,应该同样如此。它与继承层次结构非常相似。

如果我的文字解释令人困惑,请阅读下面的代码。特别是,我想解决因调用M'''G.class_method_one而导致的失败,但我缺乏这样做的知识。

我知道在我感兴趣的课程中只有H.class_method_one extend模块是可能的,但我希望避免这样做。通过A::ModuleClassMethods self.included中的A::ModuleInstanceMethods功能部分手动添加base.instance_of? Class也可以实现相同的效果,但如果可能,我想以编程方式执行,而不是复制和粘贴许多不同网站的代码相同。

module A
  module ModuleClassMethods
    def class_method_one
      2
    end
  end

  module ModuleInstanceMethods
    def instance_method_one
      3
    end

    def self.included(base)
      if base.instance_of? Class
        base.extend(A::ModuleClassMethods)
      elsif base.instance_of? Module
        # Intended functionality:
        # When modules that `include` A::ModuleInstanceMethods are themselves
        # included in a class (such as module `A::D` included in class `F`),
        # class `F` will get the functions defined in the A::ModuleClassMethods
        # module as class level methods
      end
    end
  end

  module D
    include A::ModuleInstanceMethods
  end

  module E
    include D
  end
end

class F
  include A::ModuleInstanceMethods
end

class G
  include A::D
end

class H
  include A::E
end

F.class_method_one # 2
F.new.instance_method_one # 3

G.new.instance_method_one # 3
# below statement fails
# G.class_method_one

H.new.instance_method_one # 3
# below statement fails
# H.class_method_one

谢谢。

1 个答案:

答案 0 :(得分:0)

我似乎已经弄明白了。此解决方案使用module_eval。对于module,它会添加一个调用self.included的{​​{1}}函数。我不介意学习更优雅的解决方案。

A::ModuleInstanceMethods.included