もちろん、タイトルで求めていることを実現するために、次のコードを書くことができます。
module Foo
class << self
def included receiver
my_herd << receiver
end
def my_herd; @my_herd ||= [] end
alias where_everywhere_am_I_included my_herd
end
end
Foo.where_everywhere_am_I_included #=> []
module Bar
include Foo
end
Foo.where_everywhere_am_I_included #=> [Bar]
# etc.
すべてのモジュールを検索し、それらの祖先を grep するなど、これを行うより悪い方法を想像できます。ObjectSpace
私が知りたいのは、より良い方法はありますか?method のようなものを忘れていますかModule#included_in
。たとえば、何か賢いものが欠けていますか?有名な#append_features
方法?より良い代替手段はありますか?
編集済み:私が解決している現実世界の問題は、物理単位メソッドを提供するライブラリ SY に関連しています。1.metre
、1.m
、1.s
、1.lb
、などの物理単位メソッドは、1.K
衝突しやすい単純なシンボルになる傾向があります。例えば。ActiveSupport
はすでに時間メソッド#hour
、#minute
、#second
on を定義していますNumeric
。SY は、ユニット メソッドに反応するmixin を使用して、メソッド#hour
alias #h
、#minute
alias #min
、#second
alias #s
onも定義します。しかし、 を使用する人は、、が既に定義されているため、開始しません。それでも、 、 によってメソッドにアクセスできます。Numeric
#method_missing
ActiveSupport
#hour
#minute
#second
#method_missing
SY
#h
#min
、#s
略語ですが、それは重要ではありません。要点は、ミックスインが含まれているモジュールで衝突の可能性が見つかった場合、人々に警告する必要があるということです。Module#included
これは、フックで衝突チェックをコーディングすることで簡単に実現できます。ただし、問題は、ユーザーが次のように単位を動的に定義することもできることです。
PINT = Unit.of Volume, amount: 568.26.cm³
QUART = Unit.of Volume, amount: 2.pint
#quart
しかし、ユーザーはすでに で定義されたメソッドを持っていてNumeric
、レシーバーの 1/4 を計算したり、レシーバーに対して 4 番目の音程を返したりするなど、別のことをしていると想像できますQUART = Unit#of...
。SY::ExpressibleInUnits
どこにでも混入したことを報告し、 で衝突を確認した後に警告しNumeric
ます。私は単にユーザーを驚きから救いたいだけであり、それを行うための最も有徳な ( Avdiのトレードマークの単語を使用する) 方法は何か疑問に思っています。