简体   繁体   中英

Why does `gsub!` return `nil`?

I am using a hash map to advance the character by position: "a" into "b" , etc., and to capitalize vowels.

def LetterChanges(str)
  str.to_s
  puts str
  h = ("a".."z").to_a
  i = ("b".."z").to_a.push("a")
  hash = Hash[h.zip i]
  new_str = str.downcase.gsub(/[a-z]/,hash)
  new_str.gsub!(/[aeiou]/) {|n| n.upcase }
end

LetterChanges("hello world")
LetterChanges("sentence")
LetterChanges("replace!*")
LetterChanges("coderbyte")
LetterChanges("beautiful^")
LetterChanges("oxford")
LetterChanges("123456789ae")
LetterChanges("this long cake@&")
LetterChanges("a b c dee")
LetterChanges("a confusing /:sentence:/[ this is not!!!!!!!~")

The above code works as expected except for the examples "replace!*" and "123456789ae" , for which it returns nil . Why is this?

String#gsub! modifies the original string, and returns that string or nil if no replacements were performed .

String#gsub does not modify the original string but always return the result even if nothing was changed.

Either return new_str at the end of your method, or use gsub instead of gsub! .

This is somewhat of a pattern in Ruby - when multiple version of a method exist, the one with ! will modify the receiver and the one without will simply return the result.

As an aside, it looks like you're not using the result of str.to_s for anything. If you know it's a string, to_s is pointless. If it might not be, you should make use of the result, for example like so:

str = str.to_s

String#gsub! returns nil when no substitution is performed.

new_str.gsub!(/[aeiou]/) {|n| n.upcase }

returns nil when new_str doesn't contain any vowel letters. This is the case for example, if str is "replace!*" , new_str is sfqmbdf!* , no vowels.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM