どのアプローチを使用するかについての洞察を提供するのに役立つ2つの違いがあります。あなたが安全に、プリミティブ(例えば文字列)に委任することができますが、常に安全にDelegateClass
を使用して、あなたがHash
またはString
またはFixnum
の上に構築している場合は、あなたがより安全だ、彼らから
を継承することはできません
1) (または別の委任者)。理由の詳細については、Steve Klabnik's cautioningが良い場所です)。
2)DelegateClassこれはそれが簡単に、一般的なオブジェクトのインスタンスを受け入れ、それが特定の道に動作させるためになり、より具体的な1
に、より一般的なオブジェクトを「変換」することが容易になります
class Message < DelegateClass(String)
def print
upcase
end
end
# […]
def log(message)
message = Message.new(message) unless message.is_a?(Message)
end
3)の落とし穴:あなたの実装にDelegateClass
サブクラスがnew
の引数として委任クラスのインスタンスを期待します これは、ライブラリコードに渡しているクラスを「サブクラス化」するのは難しいことがあります。たとえば、これはDelegateClass
と箱から出して動作しませんかなり一般的である:私たちのライブラリは、ほとんどのロガーのように動作し、引数なしでインスタンス化することを期待するので
class MyLogger < DelegateClass(ActiveSupport::Logger); end
Foo::ThirdParty::Library.configure do |c|
c.logger = MyLogger # no good
end
これは動作しません。これはinitialize
を定義し、ActiveSupport::Logger
というインスタンスを作成することで対応できますが、この場合はおそらく正しい解決策ではありません。