你可以扩展自我吗?包括在内吗?

时间:2013-04-09 14:52:46

标签: ruby include extend

这就是我想做的事情,粗略地说:

module Foo

  def self.included base
    base.extend ClassMethods
  end

end

module Bar
  extend Foo

  module ClassMethods
    def hi
      return "hello!"
    end
  end
end

class Baz
  include Bar
end

Baz.hi #=> "hello!'

但我得到了

NoMethodError: undefined method `hi' for Baz:Class

如果不清楚,更一般地说我要做的是创建一个包含included回调逻辑的模块,其他几个模块然后扩展,我希望它们使用{{1来自扩展模块的回调(但是,如果included扩展Bar,我希望Foo在{{1}的闭包中引用self如果可能的话。)

可能有点令人困惑。

2 个答案:

答案 0 :(得分:1)

您永远不会include Foo,因此永远不会调用included挂钩。您需要使用extended挂钩,因为您extend Foo

module Foo
  def self.extended(base)
    base.define_singleton_method(:included) do |base|
      base.extend base::ClassMethods
    end
  end
end

module Bar
  extend Foo

  module ClassMethods; def hi; 'hello!' end end
end

class Baz; include Bar end

Baz.hi #=> 'hello!'

答案 1 :(得分:0)

问题是我需要为Bar定义included而不是self.included来获取included作为类方法。以下是我想要的:

module Foo

  def included base
    base.extend self::ClassMethods
  end

end

module Bar
  extend Foo

  module ClassMethods
    def hi
      return "hello!"
    end
  end
end

class Baz
  include Bar
end

Baz.hi #=> "hello!'