コンテキスト: Ruby で Decorator パターンを作成しようとしています。Decorator はすべての不明なメソッドを基になるオブジェクトに委譲する必要があるため、Delegator クラスを使用しました。SimpleDelegator を使用することもできましたが、自分が何をしているのかを完全に理解したかったのです。
だから私が出てきた基本的なコードは次のとおりです。
class Decorator < Delegator
def initialize(component)
super
@component = component
end
def __setobj__(o); @component = o end
def __getobj__; @component end
def send(s, *a); __send__(s, *a) end
end
これは ~SimpleDelegator の実装とまったく同じです。良いようです。
しかし、私が望んでいなかったのは、Decorator を操作していることを、Decorator を処理するコードが認識できるようにすることでした。完全な透明性が必要です。
この時点でDecorator.new(Object.new).class
復帰Decorator
だから私は少しいじって、これを思いついた:
class Decorator < Delegator
undef_method :==
undef_method :class
undef_method :instance_of?
# Stores the decorated object
def initialize(component)
super
@component = component
end
def __setobj__(o); @component = o end
def __getobj__; @component end
def send(s, *a); __send__(s, *a) end
end
このようにして、装飾されたオブジェクトを安全に使用できclass
ますinstance_of?
。メソッドは、(Delegator によって実装されている) method_missing を介して基になるオブジェクトに送信されます。
問題は、なぜ undef:class
と:instance_of?
. BasicObject が定義していることがわかる:==
ので、未定義にする必要がありましたが、これら 2 つについてはどうでしょうか。BasicObject のドキュメントと C コードを少し調べましたが、何も見つかりませんでした。Delegator のドキュメントとコードも同じように調べましたが、何も見つかりませんでした。Delegator には Kernel モジュールが含まれているようですが、Kernel#class または Kernel#instance_of? 存在しません。
これらの2つの方法はどこから来たのですか? それらがまったく実装されていないのに、なぜそれらを未定義にする必要があったのでしょうか? Rubyのオブジェクトモデルか何かについて何かが欠けているに違いないと思います。
ありがとう。