jaz9090
jaz9090

Reputation: 951

gsub not working throughout code snippet

Using this code example

#!/usr/bin/ruby
paragraph = "champion xylophone excellent"
paragraph = paragraph.gsub("ch","tj")
words = paragraph.split(/ /)
words.each do |word|
   if word[0,1] == "x"
     word[0.1] = "z" 
   end
end
paragraph = words.join(" ")
paragraph.gsub("x","ks")
print paragraph

The output will be 'tjampion zylophone excellent' rather than 'tjampion zylophone ekscellent'

The same applies if the gsub is applied within the each to the individual words. I don't understand why it acts at the beginning but not at the end.

Edit

Second case is a distinct issue from the first:

#!/usr/bin/ruby
paragraph = "champion xylophone excellent"
paragraph = paragraph.gsub("ch","tj")
words = paragraph.split(/ /)
words.each do |word|
   if word[0,1] == "x"
     word[0.1] = "z" 
   end
   word = word.gsub("x","ks")
end
paragraph = words.join(" ")
print paragraph

Upvotes: 3

Views: 3659

Answers (4)

SwiftMango
SwiftMango

Reputation: 15284

paragraph.gsub!("x","ks")
puts paragraph

Or use RegExp (one line operation can do all):

paragraph = "champion xylophone excellent"
paragraph = paragraph.gsub("ch","tj").gsub(/([\A\s])x(\w*)/){$1 + 'z'+ $2}.gsub("x","ks")

puts paragraph

Upvotes: 2

steenslag
steenslag

Reputation: 80065

Your code is working by accident. The working parts use methods on strings that modify the string; the not working parts use methods that produce a new string (which is discarded). This is confusing; a better way would be to use map if the desired result is an array. It would contain the results of the block, either modified strings or new ones.

paragraph = "champion xylophone excellent"
words = paragraph.split(' ').map do |word|
  word.gsub('ch','tj') #new string
  word[0.1] = "z" if word.start_with?('x') #modified string
  word.gsub!('x','ks') #modified string
end
puts words.join(' ')

Upvotes: 2

Patrick Klingemann
Patrick Klingemann

Reputation: 9014

If you want your gsub to be destructive, i.e. to change the value of the variable on which it was called, use gsub!. so:

paragraph.gsub!('ch', 'tj')

rather than:

paragraph = paragraph.gsub('ch', 'tj')

It's more concise, and Ruby developers recognize bang (!) methods as destructive. And in your case, you need the gsub! method in place of both calls to gsub

Upvotes: 0

frostmatthew
frostmatthew

Reputation: 3298

When you first use gsub you are assigning it to paragrah

paragraph = paragraph.gsub("ch","tj")

The second time you are missing the assignment

change paragraph.gsub("x","ks") to

paragraph = paragraph.gsub("x","ks")

Upvotes: 5

Related Questions