23

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

我知道我可以通过扩展模块 ClassMethods 并通过 Module#include 钩子包含它来包含类方法。但是我可以对 prepend 做同样的事情吗?这是我的例子:

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)

FooE类:

require './Foo'

class FooE < Foo
end

和一个简单的启动脚本:

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

puts FooE.bar

当我启动脚本时,我并没有Extended Bar!像我期望的那样,而是Base Bar!. 为了正常工作,我需要改变什么?

4

2 回答 2

42

一个更简单的版本:

module Extensions
  def bar
    'Extended Bar!'
  end  
end

Foo.singleton_class.prepend Extensions
于 2015-09-01T14:37:11.410 回答
32

问题是,即使您在模块前面添加,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

于 2013-09-08T13:52:59.003 回答