How to dynamically open a method in Ruby

I want to dynamically open a method and return a value based on an input field. I am trying to ask what I want with an example here. If I could succeed in this example, I would do what I want.

Suppose I have a class called Greetings that has a greet () method that takes a message as an argument.

class Greetings
   def self.greet(message)
      return "good morning" if message=="gm"
      return "evening" if message=="ge"
      return "good afternoon" if message=="ga"
   end
end

When I do Greetings.greet("ge"), I get "evening" as an outlet. I want to change this behavior without changing the Greetings class above (the obvious reason is that its external library).

My question here is simple. What to do when I call Greetings.greet("ge"), should return to me “Very Good Evening” and for all other inputs, it should return what the original class returns. I know something about dynamically opening a class in Ruby, but how do I pass this method to the parent for other cases?

And I would write this inside the config / initializers folder, since I use Rails.

+2
source share
4 answers

Smoothing methods

You can, for example, use your old method as old_greetwell as override with yours:

class Greetings
  class << self
    alias_method :old_greet, :greet

    def greet(message)
      (message == "ge") ? "A Very Good Evening" : old_greet(message)
    end
  end
end

and then you can:

puts Greetings.greet("ge")

Method chain

Using the Rails Function alias_method_chain:

class Greetings
  class << self
    def greet_with_modifications(message)
      (message == "ge") ? "A Very Good Evening" : greet_without_modifications(message)
    end

    alias_method_chain :greet, :modifications
  end
end

and then you can:

puts Greetings.greet("ge")

Class extension

You can create your own class that extends the original as follows:

module My
  class Greetings < ::Greetings
    def self.greet(message)
      case message
        when "ge"
          "A Very Good Evening"
        else
          super(message)
      end
    end
  end
end

and then you can:

puts My::Greetings.greet("ge")
+7

- , :

Greetings.class_eval do
  class << self
    alias :old_greet :greet
  end
  def self.greet(message)
    return "a very good evening" if message == "ge"
    old_greet(message)
  end
end
+5

-

class Greetings
  class << self
    alias :old_greet :greet
  end

  def self.greet(message)
    return "A very good evening" if message == 'ge'
    old_greet(message)
  end
end
+3

, ?

class Greetings
   def self.greet(message)
      return "good morning" if message=="gm"
      return "evening" if message=="ge"
      return "good afternoon" if message=="ga"
   end
end

class GreetingsOverloaded < Greetings
  def self.greet(message)
      return "A Very Good Evenin" if message=="ge"
      super
   end
end

puts Greetings.greet("ge")
puts GreetingsOverloaded.greet("ge")
0

All Articles