Feature #10355
closedFeature request: Module#prepended?(mod)
Description
あるモジュール X に対してモジュール P1 がprependされているかどうかを調べる方法があると嬉しく思います。
Module#include?
を使うと継承関係に含まれているかどうかはわかりますが、それが対象モジュールに対してprependされたものかは分かりません。
module P1; end
module P2; end
class X
prepend P1
end
class Y< X
prepend P2
end
X.include?(P1) #=> true
Y.include?(P2) #=> true
Y.include?(P1) #=> true
# I want
X.prepended?(P1) #=> true
Y.prepended?(P2) #=> true
Y.prepended?(P1) #=> false
Updated by tagomoris (Satoshi Tagomori) about 10 years ago
ある機能が prepend によって追加されているかどうかを調べたいときに Module#include? では不十分です。
継承関係の親クラスにおいて prepend されたモジュールのメソッドは、子クラスでも定義が存在する場合、実際には呼び出されません。
module P
def myname
str = super
"p" + str
end
end
class X
def myname
"x"
end
prepend P
end
X.include?(P) #=> true
X.new.myname #=> "px"
class Y < X
def myname
"y"
end
end
Y.include?(P) #=> true
Y.new.myname #=> "y" # without prepended method
以下の方法で調べることは可能ですが冗長な上、Moduleクラスへのモンキーパッチも
通常の用途ではためらわれるため、標準でサポートされていると助かります。
class Module
def prepended?(mod)
self.ancestors.include?(mod) && self.ancestors.index(mod) < self.ancestors.index(self)
end
end
Updated by tagomoris (Satoshi Tagomori) about 10 years ago
特定メソッドの出力のフィルタをprependによって実現したい場合、親クラスで既にprependされていても子クラスでメソッド定義が上書きされればprependが実際には効かないことになります。
このような状態が起きてないかどうかを調べる必要がある(起きていればprependしなおす)、というケースで Module#prepended? 相当の機能が必要となります。
フレームワークなどの記述において、DI等で挿入されたオブジェクトの機能を調べてコントロールする用途などで必要です。
Updated by nobu (Nobuyoshi Nakada) about 10 years ago
- Description updated (diff)
- Category set to core
- Status changed from Open to Feedback
- Assignee set to matz (Yukihiro Matsumoto)
- Target version set to 2.2.0
このメソッドに反対なわけではないですが、メソッド定義が上書きされているかどうかを調べたいのであれば、UnboundMethod#owner
などを使うほうがいいのではないでしょうか。
Updated by tagomoris (Satoshi Tagomori) about 10 years ago
メソッド定義が上書きされているかどうかを調べたいというより、誰がownerでもいいけど確実にprependされていてほしい、という方が要求として正確なように思います。
Updated by tagomoris (Satoshi Tagomori) about 10 years ago
提案する名前について prepended?
は正しくありませんでした。prepend?
が正しいです。訂正します。
Updated by naruse (Yui NARUSE) almost 7 years ago
- Target version deleted (
2.2.0)