2010-10-19 5 views
0

Я хочу, чтобы преобразовать имя "JOHN DOE-SMITH", чтобы "John Doe-Смит" с помощью кода:назначение рубин внутри итератора

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(" ") 

Результатом является неожиданным "Джон DOE-СМИТ"
Почему x.capitalize! имеют эффект, тогда как x = "foo" не имеет?
Есть ли лучший способ сделать это?

ответ

0

Как насчет

cap_name = name.split.map{|w| w.split("-").map(&:capitalize).join("-") }.join(" ") 
1

x = "foo" просто присваивает переменной x ссылку на другой объект. Поскольку эта переменная существует только в блоке, это не имеет наблюдаемого эффекта. Он не меняет строку вообще. x.capitalize!, с другой стороны, отправляет сообщение capitalize! в строку, что приводит к его изменению.

0

Поскольку x - это локальная переменная, указывающая на строку с использованием тех же данных. Вот почему влияние на него нового значения не меняется внутри строки.

Возможно, вы захотите немного переосмыслить свою стратегию; это зависит от того, что строка разделения относится к той же области памяти, что и исходная строка, которую я бы не поставил, имеет место во всех случаях.
я предлагаю использовать вместо .map:

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(" ") 

Или, если вы находите это более удобным для чтения:

name_split = name.split(/\s/).map do |x| 
    x.split(/-/).map(&:capitalize).join('-') 
end 
puts name_split.join(" ") 
Смежные вопросы