如何预先添加类方法

时间:2013-09-08 12:38:15

标签: ruby

这个问题直接与this one有关。但我试图将其分解为基本问题,我不想在另一个问题框中输入更多文本。所以这里:

我知道我可以通过扩展模块ClassMethods并通过Module #include钩子来包含classmethods。但我可以在前置时做同样的事情吗?这是我的例子:

class Foo:

class Foo
  def self.bar
    'Base Bar!'
  end
end 

类扩展:

module Extensions
  module ClassMethods
    def bar
      'Extended Bar!'
    end
  end

  def self.prepended(base)
    base.extend(ClassMethods)
  end
end
# prepend the extension 
Foo.send(:prepend, Extensions)

class FooE:

require './Foo'

class FooE < Foo
end

和一个简单的启动脚本:

require 'pry'
require './FooE'
require './Extensions'

puts FooE.bar

当我启动脚本时,我不会像我期望的那样得到Extended Bar!,而是Base Bar!。为了正常工作,我需要更改什么?

2 个答案:

答案 0 :(得分:37)

更简单的版本:

module Extensions
  def bar
    'Extended Bar!'
  end  
end

Foo.singleton_class.prepend Extensions

答案 1 :(得分:26)

问题在于,即使您正在使用该模块,ClassMethods仍在进行extend。您可以这样做以获得您想要的内容:

module Extensions
  module ClassMethods
    def bar
      'Extended Bar!'
    end  
  end  

  def self.prepended(base)
    class << base
      prepend ClassMethods
    end  
  end  
end

请注意,Extensions本身可以预先添加或包含在Foo中。重要的是预先ClassMethods