seza443 seza443 - 1 year ago 66
Ruby Question

Ruby reflection composition: call original method from redefined method

A bit of context first

I have a class
that defines a method
like this:

class Phone
def advertise(phone_call)

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)

Then my program can do

# add the module to the class so that we can redefine the method
# 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.advertise(a_call) # -> 'ringtone'
# do some adaptation stuff to redefine the method
phone.advertise(a_call) # -> 'vibrator'

Finally coming to my question

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'

But I don't know what the
call should do or even where should I define it.

  • I'm using Ruby 2.3.0 on Windows.

  • 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.

Answer Source

In my opinion, this approach is way too complex, and an inappropriate use of Modules.

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

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

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

    def ring

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download