I have a class Phone
that defines a method advertise
like this:
class Phone
def advertise(phone_call)
'ringtone'
end
end
I would like to have some adaptations for this method. For example when the user is in a quiet environment, the phone should vibrate and not ring. To do so, I define modules like
module DiscreetPhone
def advertise_quietly (phone_call)
'vibrator'
end
end
Then my program can do
# 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 ))
Of course for this example I hardcoded the class and module's name but they should be parameters of a function.
And so, an execution example would give:
phone = Phone.new
phone.advertise(a_call) # -> 'ringtone'
# do some adaptation stuff to redefine the method
...
phone.advertise(a_call) # -> 'vibrator'
I want to have an adaptation that call the original function and append something to its result. I would like to write it like
module ScreeningPhone
def advertise_with_screening (phone_call)
proceed + ' with screening'
end
end
But I don't know what the proceed
call should do or even where should I define it.
proceed
could be replaced by something else but I'd like to keep it as clean as possible in the module that defines the adaptation.In my opinion, this approach is way too complex, and an inappropriate use of Module
s.
I recommend thinking about a simpler way to implement this.
One simple way is to just include all the methods in the Phone class.
Or, you could use a hash as a lookup table for ring strategies:
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