Question

Is it possible to monkey-patch a method with a bang at the end?

I want to monkey-patch String.upcase!, but I don't know how to achieve that.

The problem is that I want to change the original string object.

Here's an example:

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

Now if I type that in console and try it out, it doesn't work:

[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"
Was it helpful?

Solution 2

Your issue is independent of the method having a bang. If you want to replace the receiver string, use the method String#replace.

class String
  def foo
    replace(whatever_string_you_want_to_replace_the_receiver_with)
  end
end

You can perhaps put mb_chars.upcase as the argument to replace.

OTHER TIPS

You should avoid monkey patching top-level class like String. If you want to know why, I strongly recommend you to read Monkeypatching is Destroying Ruby by Avdi Grimm.

Now to answer your question, you could do something like this:

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"

The bang is just part of the method name. It has absolutely no special meaning whatsoever. You write a method with a bang at the end the exact same way you write a method with an 'o' or a 'z' at the end.

How about:

class String
  def upcase!
     #Your logic here
  end
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top