2

我有一个模块,可以在包含到类中时添加类方法。

我想通过编写将包含在第一个模块中的另一个模块来强制该模块扩展新方法。

下面的代码给出了一个我想做但不起作用的例子:如果能够覆盖第一个模块的“self.included”函数来用我的方法扩展基础,那就太好了。

到目前为止,我能够覆盖第一个模块的 self.included 函数,但调用 super 不起作用,所以我放弃了第一个模块的类方法:

module SomeModule

  def self.included(base)
    base.send(:extend, ClassMethods)
  end

  module ClassMethods

    # Some methods

  end

end


module MyNewModule

 def self.included(base)
    base.class_eval do
      def self.included(base)
        base.send(:extend, ClassMethods)
        super(base)
      end
    end
  end

  module ClassMethods

    def my_method
    end

  end

end

SomeModule.send(:include, MyNewModule)

class Pouet

  include SomeModule

  my_method # undefined local variable or method `my_method' for Pouet:Class (NameError)

end

这可能吗?

4

2 回答 2

1

在包含的块中使用 instance_eval。

在 instance_eval 块中,您可以访问包含它的对象,因此您应该能够在其中包含额外的模块。

编辑:

您必须将字符串传递给 instance_eval,因为该块将存储您当前的上下文。

对于我做过类似的例子:https ://github.com/JoePym/UndergroundFootball/blob/master/app/models/player.rb#L14

于 2013-01-31T17:01:21.093 回答
0

终于设法让它自己工作。

请告诉我这是一个好还是坏的做法:

module SomeModule

  def self.included(base)
    base.send(:extend, ClassMethods)
  end

  module ClassMethods

    def my_original_method
    end

    # Some methods

  end

end


module MyNewModule

  def self.included(base)
    base.class_eval do

      class << self

        alias_method :old_included, :included

        def included(base)
          old_included(base)
          base.send(:extend, ClassMethods)
        end

      end

    end
  end

  module ClassMethods

    def my_method
    end

  end

end

SomeModule.send(:include, MyNewModule)

class Pouet

  include SomeModule

  my_original_method
  my_method

end
于 2013-01-31T17:26:20.043 回答