如何在Ruby中动态打开方法

时间:2011-05-04 13:43:02

标签: ruby-on-rails ruby dynamic methods

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

假设我有一个名为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

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

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

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

4 个答案:

答案 0 :(得分: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

然后你可以:

puts Greetings.greet("ge")

方法链

使用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

然后你可以:

puts Greetings.greet("ge")

扩展课程

您可以创建自己的类,扩展原始类:

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

然后你可以:

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

答案 1 :(得分: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

答案 2 :(得分:3)

您可以执行类似

的操作
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 :(得分:0)

这个怎么样,干脆?

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")