0

最初に少しコンテキスト

次のようなPhoneメソッドを定義するクラスがあります。advertise

class Phone
  def advertise(phone_call)
    'ringtone'
  end
end

この方法については、いくつかの適応が必要です。たとえば、ユーザーが静かな環境にいる場合、電話は振動し、鳴らないはずです。そうするために、次のようなモジュールを定義します

module DiscreetPhone    
  def advertise_quietly (phone_call)
    'vibrator'
  end
end

それから私のプログラムはできる

# add the module to the class so that we can redefine the method
Phone.include(DiscreetPhone) 
# redefine the method with its adaptation
Phone.send(:define_method, :advertise, DiscreetPhone.instance_method(:advertise_quietly ))

もちろん、この例では、クラスとモジュールの名前をハードコーディングしましたが、それらは関数のパラメーターである必要があります。

したがって、実行例は次のようになります。

phone = Phone.new
phone.advertise(a_call) # -> 'ringtone'
# do some adaptation stuff to redefine the method
...
phone.advertise(a_call) # -> 'vibrator'

最後に私の質問に来ます

元の関数を呼び出し、その結果に何かを追加する適応が必要です。のように書きたいと思います。

module ScreeningPhone
  def advertise_with_screening (phone_call)
    proceed + ' with screening'
  end
end

proceedしかし、呼び出しが何をすべきか、どこで定義すればよいかさえわかりません。

  • WindowsでRuby 2.3.0を使用しています。
  • proceed他のものに置き換えることもできますが、適応を定義するモジュールでできるだけきれいに保ちたいと思います。
4

2 に答える 2

0

私の意見では、このアプローチは複雑すぎて、Modules の不適切な使用です。

これを実装するためのより簡単な方法を検討することをお勧めします。

簡単な方法の 1 つは、すべてのメソッドを Phone クラスに含めることです。

または、ハッシュをリング戦略のルックアップ テーブルとして使用できます。

class Phone

    attr_accessor :ring_strategy

    RING_STRATEGIES = {
        ringtone:  -> { ring_with_tone },
        discreet:  -> { ring_quietly },
        screening: -> { ring_with_tone; ring_screening_too }
        # ...
    }

    def initialize(ring_strategy = :ringtone)
        @ring_strategy = ring_strategy
    end

    def ring
        RING_STRATEGIES[:ring_strategy].()
    end

end
于 2016-05-08T14:51:18.673 に答える