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?
2 Answers
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".
3 Comments
replace was incorrect.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
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.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.
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"