4

replace alters the current string rather than returning a new instance. To be consistent with other methods in Ruby it seems like should be called replace! Is this a bug/inconsistency or is there something I've missed?

3
  • 2
    @sawa he has also mentioned that he might have missed something.. so chill :) Commented Sep 16, 2015 at 13:28
  • @sawa I'd tried to make the tone of my question reflect this. The very reason I asked this question was I'd wondered what I'd misunderstood as ruby is general consistent. Thanks to pyRabbit 's comment I found out something about what bang(!) means. Commented Sep 16, 2015 at 13:30
  • 1
    BTW, there are several destructive method without a bang: clear, concat, insert, prepend, ... The documentation even mentions this: "Typically, methods with names ending in "!" modify their receiver, while those without a "!" return a new String. However, there are exceptions" Commented Sep 16, 2015 at 13:32

2 Answers 2

4

From matz's post here https://www.ruby-forum.com/topic/176830#773946

The bang (!) does not mean "destructive" nor lack of it mean non destructive either. The bang sign means "the bang version is more dangerous than its non bang counterpart; handle with care". Since Ruby has a lot of "destructive" methods, if bang signs follow your opinion, every Ruby program would be full of bangs, thus ugly.

So the initial question comes from a misunderstanding of what the bang (!) means. There's not a bang because it only makes sense to have a single replace method so there's no need to mark it as "more dangerous".

Sign up to request clarification or add additional context in comments.

3 Comments

You understand that it was a misunderstanding of yours because you are the OP. You didn't even write in the question that you thought that the bang meant destructive.
That would make your question clearer, but notice that that would also change the question.
I'm not sure about that. The question (as intended) came about from some confusion at work. I understood the ! to mean destructive methods on a string. Which is why it felt that replace was incorrect.
2

No. Whenever you want a new string that is in no way related to another existing string, there is no point in creating the new string out of the existing string. For example, suppose there were a String method create_new_string that creates a new string instance out of an existing string by replacing the content with the given argument as follows:

"foo".create_new_string("bar")
# => "bar" 

It is easy to see that that does not make sense. You can, and should, rather create a new string using a string literal:

"bar"
# => "bar"

Therefore, there is no point in having a String method that in-destructively creates a new string by replacing its content; a meaningful method that would replace the content of string should destructively replace the content of the receiver string and return that string without surprise. Hence, no need for a bang.

6 Comments

For clarity, I think it is important to note that this method cannot be any more destructive then it already is. That is why there is no "bang" counterpart. See Matz' post ruby-forum.com/topic/176830#773946
@sawa I understand why there is only a single replace method (which your answer sums up very nicely). But I find it surprising that all other methods which alter the string in place end with a bang. Where as this one doesn't. Basically I expected replace! and no replace and I wondered why this wasn't the case.
Having just read @pyRabbit 's answer it makes more sense to me. I hadn't realised the bang was to indicated a "more dangerous than its non bang counterpart" version.
@SteveB that is right. The tl;dr of Matz' post is that the "bang" isn't necessarily indicative of a method being destructive or not. He makes a good point that if that were the case, Ruby code would be inundated with bangs.
@SteveB: "all other methods which alter the string in place end with a bang" – Not true: clear, concat, force_encoding, insert, prepend, setbyte, <<, and []= also have no bang and modify the receiver. Several of those also exist for Array and Hash with the same semantics. Array also has pop, push, shift, and unshift. Then there's Kernel#exit and Kernel#exit! which have nothing to do with mutating the receiver.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.