Feature #10927


[PATCH] Add default empty string to string replacements

Added by zimbatm (zimba tm) almost 8 years ago. Updated over 7 years ago.

Target version:


Hi ruby devs !

A common case for string substitution is to just remove the found items. This patch changes the String#[g]sub[!] methods to allow that.

Old usages:

"foo".sub("o", "") #=> "fo"
"foo".gsub("o", "") #=> "f"

New usages:

"foo".sub("o") #=> "fo"
"foo".gsub("o") #=> "f"

Applies to the bang versions as well.

This commit changes the return values of String#gsub! call with a single
argument and no block from an Enumerator to a String. The previous usage
would return an Enumerator containing each match, which is not a string
substitution. A suitable replacement should nonetheless be found before
merging this commit.


"foo".gsub("o") #=> #<Enumerator: "foo":gsub("o")>




Updated by shevegen (Robert A. Heiler) almost 8 years ago

I don't think this is likely to get in because it breaks backwards compatibility.

The prior usage could well be a case for .delete when it comes to .gsub:

"foo".delete("o") #=> "f"

Perhaps .delete could allow to replace just n occurences instead, to also
allow .sub behaviour, such as:

"foo".delete('o',1) #=> "fo"

Updated by duerst (Martin Dürst) almost 8 years ago

Robert A. Heiler wrote:

I don't think this is likely to get in because it breaks backwards compatibility.

Not only that. The proposed change may be for a somewhat frequent use case, but it does not save too many characters in code nor does it make things more readable. It also does not lead to new, potentially not yet thought-of usages.

Updated by zimbatm (zimba tm) over 7 years ago

Alright but a change doesn't necessarily need to be substantial to improve developer happiness. It seems like my little hack has two aspects to it that I would like to address separately.

"foo".gsub("o") currently doesn't do any substitution. In my point of view it's a hack to get an Enumerator instead of an Array (which #scan returns) and should therefor be deprecated to leave room for other usages (like the one I proposed). I am happy to propose a patch that adds a warning on that usage.

There's a lot of times where I just want to remove some string or regexp match from a string and just being able to some_string.gsub(pattern) would make me happy. I don't think it's a too big change if backward-compatibility is not broken. That will have to wait until the first point is resolved.

Updated by duerst (Martin Dürst) over 7 years ago

zimba tm wrote:

"foo".gsub("o") currently doesn't do any substitution.

At that point indeed it's just an enumerator. But just try the following:
e = "foo".gsub("o")
=> Enumerator
irb(main):010:0> e.each { 'OXO' }
=> "fOXOOXO"
irb(main):011:0> e.each { 'XOX' }
=> "fXOXXOX"

This is definitely doing some substitution. And you can use the same enumerator to create many different new strings. That's what I meant by "lead to new, potentially not yet thought-of usages".


Also available in: Atom PDF