Your code returns the modification of say, but does change the contents of the variable. It appears that you want to modify the argument, but I'm not sure about that. I will first suggest a way to return the modified value of say (but not alter the value of say, and then will show how you could change the code to modify the argument.
Notice that I do not employ an index, and use a case statement to determine whether words after the first should be capitalized.
Code
def titleize(say)
words = say.split
return "" if words.empty?
words.first.capitalize!
return words.first if words.size == 1
words[1..-1].each do |word|
case word
when "and", "or", "over", "the", "for"
else
word.capitalize!
end
end
words.join(' ')
end
Examples
say = "and now is the time for all Rubyists to hunker down and code"
titleize(say)
#=> "And Now Is the Time for All Rubyists To Hunker Down and Code"
say
#=> "and now is the time for all Rubyists to hunker down and code"
say = " "
titleize(say)
#=> ""
say = " and "
titleize(say)
#=> "And"
Modifying the Argument
If you wish to modify the argument say, use String#replace:
def titleize_and_modify_arg(say)
words = say.split
str =
case words.size
when 0
""
when 1
words.first.capitalize
else
words.first.capitalize!
words[1..-1].each do |word|
case word
when "and", "or", "over", "the", "for"
else
word.capitalize!
end
end
words.join(' ')
end
say.replace(str)
end
say = "and now is the time for all Rubyists to hunker down and code"
titleize_and_modify_arg(say)
#=> "And Now Is the Time for All Rubyists To Hunker Down and Code"
say
#=> "And Now Is the Time for All Rubyists To Hunker Down and Code"
say = " and "
titleize_and_modify_arg(say)
#=> nil
say
#=> " and "
Notice that in the second example, titleize_and_modify_arg modifies say correctly, but returns nil. Of course, the method could be easily changed to return the value of say, as well as changing it, if that were desired.
Note also that, in the case statement, when words.siz => 1, it's capitalize, not capitalize!, as the latter would return nil if the word is already capitalized. capitalize! is need for the else case, however.
word == "and" || "or" || "over" || "the" || "for"parses as(word == "and") || ("or") || ("over") || ("the") || ("for"), which will always return a truthy value.