Ruby 模块包含,无法访问包含的方法,只能访问常量

kdb*_*man 2 ruby methods module mixins

我有一个这样的模块结构:

module Parent

  PARENT_CONST = 'parent const'

  def Parent.meth
    puts 'parent meth'
  end

end

module Child
  include Parent
end
Run Code Online (Sandbox Code Playgroud)

这按预期工作:

puts Parent::PARENT_CONST
 => parent const
Parent.meth
 => parent meth
Run Code Online (Sandbox Code Playgroud)

我可以从孩子访问父母的常量,但不能访问方法。像这样:

Child::PARENT_CONST
 => parent const
Child.meth
 => in `<main>': undefined method `meth' for Child:Module (NoMethodError)
Run Code Online (Sandbox Code Playgroud)

有没有办法让我做到这一点?

Car*_*and 5

下面是一种将包含常量、实例方法和类方法的模块混合到一个类中的常用方法,但它也可以用于将一个模块的常量和类方法包含在另一个模块中,这就是你想要做的。它使用“回调”或“钩子”方法Module#includedObject#extend在模块中添加实例方法,该模块是extend接收者模块的参数。下面它Public::C_Meths在模块中的类方法中创建实例方法(这里只有一个)Child

module Parent
  module I_Meths
    PARENT_CONST = 'parent const'
  end

  module C_Meths
    def cmeth
      'cmeth'
    end
  end

  def self.included(mod)
    mod.include(I_Meths)
    mod.extend(C_Meths)
  end
end

module Child
  include Parent
end

Child::PARENT_CONST
  #=> "parent const" 
Child.cmeth
  #=> "cmeth" 
Run Code Online (Sandbox Code Playgroud)

更常见的是使用此构造将包含约束、实例方法和类方法的模块混合到一个类中。

假设我们要添加实例方法:

def imeth
  'imeth'
end
Run Code Online (Sandbox Code Playgroud)

到模块Parent::I_Methsinclude Parent类中:

class A
  include Parent
end
Run Code Online (Sandbox Code Playgroud)

然后

A::PARENT_CONST
  #=> "parent const" 
A.cmeth
  #=> "cmeth" 
A.new.imeth
  #=> "imeth"
Run Code Online (Sandbox Code Playgroud)