最近我不得不为Redmine的核心类添加一个方法。我无法使用继承,所以我做了类似的事情:
require_dependency 'time_entry_query'
class TimeEntryQuery < Query
def my_new_method(foo, bar)
end
end
它完美无缺 - 我的方法被添加到所有新对象中。但是,我看到有人在他们自己的模块中声明了新方法,然后发送:include到class,所以它变成了mixin。这是一个例子:
module Patches
module SomeClassPatch
def my_new_method
end
end
在应用初始化的某个地方:
SomeClass.send(:include, Patches::SomeClassPatch) unless SomeClass.include? (Patches::SomeClassPatch)
这两种方法之间有什么区别?我应该使用哪种方法?
答案 0 :(得分:1)
有两点不同:
当您使用mixin时,您的“补丁”方法可以存在一个明确的位置。如果我想知道“嗯,这个my_new_method
来自哪里,我看,TimeEntryQuery.ancestors
或TimeEntryQuery.instance_method(:my_new_method).owner
,那将返回Patches::SomeClassPatch
。所以我知道我必须在某个地方寻找一个名为lib/patches/some_class_patch.rb
的文件来查找它可能定义的位置。 (我也可以尝试source_location
,但这并不总是可靠的。)
将模块混合到类中会使模块成为混合类的超类。因此,如果my_new_method
中已定义TimeEntryQuery
,则您的第一个选项将覆盖它,而在第二个选项中,您的方法将成为该方法的super
方法。 IOW:使用第二个选项,除非现有方法调用super
,否则不会调用新方法。