0

最近我不得不在 Redmine 的核心类中添加一个方法。我无法使用继承,所以我做了这样的事情:

require_dependency 'time_entry_query'
class TimeEntryQuery < Query
    def my_new_method(foo, bar)
    end
end

它工作得很好——我的方法被添加到所有新对象中。但是,我看到有人在他们自己的模块中声明了新方法,然后将 :include 发送到类,所以它变成了一个 mixin。这是一个例子:

module Patches
  module SomeClassPatch
    def my_new_method
    end
end

在应用程序初始化的某个地方:

SomeClass.send(:include, Patches::SomeClassPatch) unless SomeClass.include? (Patches::SomeClassPatch)

这两种方法有什么区别,我应该使用哪一种?

4

1 回答 1

1

有两个区别:

  1. 当您使用 mixin 时,您的“补丁”方法可以存在一个明确的位置。如果我想知道“嗯,这是从哪里来的my_new_method”,然后我看,说,TimeEntryQuery.ancestors或者TimeEntryQuery.instance_method(:my_new_method).owner,那将返回Patches::SomeClassPatch。所以我知道我必须寻找一个名为lib/patches/some_class_patch.rb某处的文件才能找到它可能定义的位置。(我也可以尝试source_location,但这并不总是可靠的。)

  2. 将一个模块混入一个类使该模块成为它被混入的类的超类。因此,如果已经my_new_method定义了 in TimeEntryQuery,您的第一个选项将覆盖它,而在您的第二个选项中,您的方法将成为该super方法的方法。IOW:使用第二个选项,除非现有方法调用,否则不会调用您的新方法super

于 2013-09-24T22:22:07.637 回答