如何在 Ruby 中动态打开方法

发布于 2024-11-05 04:56:03 字数 667 浏览 0 评论 0原文

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

假设我有一个名为 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") 时,我得到“evening”作为输出。我想改变这种行为而不改变上面的 Greetings 类(明显的原因是它是一个外部库)。

我的问题很简单。当我调用 Greetings.greet("ge") 应该返回“A Very Good Evening”并且对于所有其他输入时,我应该做什么,它应该返回原始类返回的内容。我知道一些有关在 Ruby 中动态打开类的知识,但是在其他情况下我如何将该方法委托给父类?

因为我使用的是 Rails,所以我会将其写在 config/initializers 文件夹中。

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

Assume I have a class called Greetings which has a method called greet() which takes message as 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 a Greetings.greet("ge"), I get "evening" as the output. I want to change this behavior without changing the above Greetings class (obvious reason is that its an external library).

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

And I would be writing this inside the config/initializers folder since I am using Rails.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

蓝天 2024-11-12 04:56:03

方法别名

例如,您可以将旧方法别名为 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")

Method aliasing

You can alias your old method as old_greet for example, and redefine with your own:

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 chaining

With the Rails alias_method_chain feature:

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

Extending class

You can create your own class which extends the original like this:

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")
哑剧 2024-11-12 04:56:03

您可以执行以下操作来重新打开代码中的类:

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

You could do something like this to reopen the class in your code:

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
等待我真够勒 2024-11-12 04:56:03

你可以做类似的事情

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

You could do something like

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
无声无音无过去 2024-11-12 04:56:03

简单来说这个怎么样?

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

What about this, simply?

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")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文