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)

これら 2 つの方法の違いと、どちらを使用する必要がありますか?

4

1 に答える 1

1

次の 2 つの違いがあります。

  1. ミックスインを使用すると、「パッチ」メソッドが存在できる明確な場所があります。「うーん、これはどこ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定義されているTimeEntryQuery場合、最初のオプションはそれを上書きしますが、2 番目のオプションでは、superメソッドはそのメソッドのメソッドになります。IOW: 2 番目のオプションでは、既存のメソッドが を呼び出さない限り、新しいメソッドは呼び出されませんsuper

于 2013-09-24T22:22:07.637 に答える