Project

General

Profile

Actions

Feature #10355

closed

Feature request: Module#prepended?(mod)

Added by tagomoris (Satoshi Tagomori) over 9 years ago. Updated about 6 years ago.

Status:
Feedback
Target version:
-
[ruby-dev:48610]

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) over 9 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) over 9 years ago

特定メソッドの出力のフィルタをprependによって実現したい場合、親クラスで既にprependされていても子クラスでメソッド定義が上書きされればprependが実際には効かないことになります。
このような状態が起きてないかどうかを調べる必要がある(起きていればprependしなおす)、というケースで Module#prepended? 相当の機能が必要となります。

フレームワークなどの記述において、DI等で挿入されたオブジェクトの機能を調べてコントロールする用途などで必要です。

Updated by nobu (Nobuyoshi Nakada) over 9 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) over 9 years ago

メソッド定義が上書きされているかどうかを調べたいというより、誰がownerでもいいけど確実にprependされていてほしい、という方が要求として正確なように思います。

Updated by tagomoris (Satoshi Tagomori) over 9 years ago

提案する名前について prepended? は正しくありませんでした。prepend? が正しいです。訂正します。

Actions #6

Updated by naruse (Yui NARUSE) about 6 years ago

  • Target version deleted (2.2.0)
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0