发送:include到class和直接定义第二类定义中的方法有什么区别?

时间:2013-09-24 20:27:08

标签: ruby-on-rails ruby inheritance mixins redmine-plugins

最近我不得不为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)

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

1 个答案:

答案 0 :(得分:1)

有两点不同:

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

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