【问题标题】:Monkey-patching ruby method with bang用 bang 修补 ruby​​ 方法
【发布时间】:2013-10-14 15:29:09
【问题描述】:

是否可以在结尾处用 bang 对方法进行猴子修补?

我想对 String.upcase! 进行猴子补丁,但我不知道如何实现。

问题是我想改变原来的字符串对象。

这是一个例子:

class String
  def upcase!
    self.mb_chars.upcase.to_s
  end
end

现在,如果我在控制台中输入并尝试,它不起作用:

[1] pry(main)> asd="asd"
=> "asd"
[2] pry(main)> asd.upcase
=> "ASD"
[3] pry(main)> asd
=> "asd"
[4] pry(main)> asd.upcase!
=> "ASD"
[5] pry(main)> asd
=> "asd"

【问题讨论】:

  • 这和最后没有爆炸的方法没什么不同
  • 警告:你的有责任让方法修改调用者,如果这是你想要的。但这与您有责任修改调用者时没有什么不同。

标签: ruby monkeypatching


【解决方案1】:

您应该避免猴子修补顶级类,例如String。如果你想知道为什么,我强烈建议你阅读Monkeypatching is Destroying Ruby by Avdi Grimm

现在回答你的问题,你可以这样做:

class String
  def upcase!
    replace(upcase) # self is not mandatory here
  end
end

> s = "foo"
 => "foo"
> s.upcase
 => "FOO"
> s
 => "foo"
> s.upcase!
 => "FOO"
> s
 => "FOO"

【讨论】:

    【解决方案2】:

    您的问题与成功的方法无关。如果要替换接收者字符串,请使用方法String#replace

    class String
      def foo
        replace(whatever_string_you_want_to_replace_the_receiver_with)
      end
    end
    

    您也许可以将mb_chars.upcase 作为replace 的参数。

    【讨论】:

      【解决方案3】:

      bang 只是方法名称的一部分。它绝对没有任何特殊含义。您编写一个结尾带有 bang 的方法,与编写结尾带有 'o' 或 'z' 的方法完全相同。

      【讨论】:

        【解决方案4】:

        怎么样:

        class String
          def upcase!
             #Your logic here
          end
        end
        

        【讨论】:

        • 我需要替换原始字符串。我知道我可以写出你写的东西,但是你能告诉我一些可以替换原始字符串的例子吗?
        • 抱歉,我不太明白您要处理的问题是什么。请更新问题并提供更多详细信息。
        猜你喜欢
        • 2017-05-24
        • 2011-12-15
        • 1970-01-01
        • 1970-01-01
        • 2013-07-14
        • 2021-09-03
        • 2012-05-07
        • 2011-07-26
        • 1970-01-01
        相关资源
        最近更新 更多