Ruby assignment inside an iterator
I want to convert the name "JOHN DOE-SMITH" to "John Doe-Smith" using the code:
name = "JOHN DOE-SMITH"
name_split = name.split(/\s/)
name_split.each do |x|
if x =~ /-/
name1, name2 = x.split(/-/)
x = name1.capitalize + "-" + name2.capitalize
else
x.capitalize!
end
end
puts name_split.join(" ")
The result is the unexpected "John DOE-SMITH"
Why does x.capitalize! have an effect while x = "开发者_如何学Gofoo" has none? Is there a better way to do this?x = "foo"
just assigns the variable x
to reference a different object. Since that variable only exists in the block, this has no observable effect. It doesn't change the string at all. x.capitalize!
, on the other hand, sends the capitalize!
message to the string, which causes it to change case.
How about
cap_name = name.split.map{|w| w.split("-").map(&:capitalize).join("-") }.join(" ")
Because x is a local variable that points to a string using the same data. This is why affecting a new value to it doesn't change inside the string.
You might want to rethink a little your strategy here ; it is dependant on the fact that the split string refers to the same memory area as the original string, which I wouldn't bet holds true in all cases.
I'd suggest to use .map instead:
name_split = name.split(/\s/).map do |x|
if x =~ /-/
name1, name2 = x.split(/-/)
name1.capitalize + "-" + name2.capitalize
else
x.capitalize
end
end
puts name_split.join(" ")
Or if you find this more readable:
name_split = name.split(/\s/).map do |x|
x.split(/-/).map(&:capitalize).join('-')
end
puts name_split.join(" ")
精彩评论