Использование слова в массив, Рубин
Я просматриваю вопросы Ruby Prep Академии приложений, и я хочу знать, почему это решение работает. Похоже, что массив слов никогда не изменяется, и все же метод работает. Это сбой в матрице, или он прямо у меня под носом?
def capitalize_words(string)
words = string.split(" ")
idx = 0
while idx < words.length
word = words[idx]
word[0] = word[0].upcase
idx += 1
end
return words.join(" ")
end
3 ответа:
String#[]=
это мутирующая операция. Для иллюстрации приведем краткую выдержку из вашего кода:word = "foo" word[0] = word[0].upcase # <-- verbatim from your code word #=> "Foo"
word
это все тот же точный объект, содержащийся в массивеwords
(массивы просто содержат ссылки на объекты, а не данные внутри них), но он был мутирован на месте. Обычно лучше избегать мутаций, когда это возможно, поскольку это делает неочевидным то, что происходит (как вы можете видеть).Ваш код также может быть написан более лаконично использование
map
&capitalize
(и без всяких мутаций):string.split(' ').map(&:capitalize).join(' ')
Метод работает потому, что
word
содержит ссылку на позицию массива. Поэтому, когда вы назначаете:word = words[idx]
Вы просто используете
word
в качестве сокращения для работы с этим элементом массива, который модифицируется:word[0] = word[0].upcase
--
Кроме того, если вы хотите вернуться к этому ответу после изучения некоторых Ruby, вот упрощенная версия метода:
def capitalize_words(string) string.split.map(&:capitalize).join(' ') end
word = word[idx]
создает копию ваших данных. Затем он изменит эту копию вместо слов в исходном массиве.Простое решение будет следующим:
def capitalize_words(string) words = string.split(" ") idx = 0 while idx < words.length words[idx][0] = words[idx][0].upcase idx += 1 end return words.join(" ") end