如何在Ruby中动态打开方法

bra*_*boy 2 ruby methods ruby-on-rails dynamic

我想动态打开一个方法并根据输入字段返回一个值.我试图用这里的例子问我想要什么.如果我能成功这个例子,我会做我想做的事.

假设我有一个名为Greetings的类,它有一个名为greet()的方法,它将消息作为参数.

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
Run Code Online (Sandbox Code Playgroud)

当我做的时候Greetings.greet("ge"),我把"晚上"作为输出.我想改变这种行为而不改变上面的Greetings类(显而易见的原因是它是一个外部库).

我的问题很简单.说我打电话时应该怎么做才能给Greetings.greet("ge")我回复"非常晚安",对于所有其他输入,它应该返回原始类返回的内容.我知道在Ruby中动态打开一个类但是如何将该方法委托给其他情况的父类?

我会在config/initializers文件夹中写这个,因为我正在使用Rails.

KAR*_*ván 7

方法别名

old_greet例如,您可以为旧方法设置别名,并使用您自己的方法重新定义:

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

    def greet(message)
      (message == "ge") ? "A Very Good Evening" : old_greet(message)
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

然后你可以:

puts Greetings.greet("ge")
Run Code Online (Sandbox Code Playgroud)

方法链

使用Rails 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
Run Code Online (Sandbox Code Playgroud)

然后你可以:

puts Greetings.greet("ge")
Run Code Online (Sandbox Code Playgroud)

扩展课程

您可以创建自己的类,扩展原始类,如下所示:

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

然后你可以:

puts My::Greetings.greet("ge")
Run Code Online (Sandbox Code Playgroud)


Dyl*_*kow 5

你可以做这样的事情来重新打开代码中的类:

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
Run Code Online (Sandbox Code Playgroud)

  • 重新打开类,如果该类尚不存在,它将创建它.使用class_eval,如果该类尚不存在,则将引发错误. (3认同)