Почему этот метод.each_char не заменит указанный символ?

Это простой и простой вопрос. В приведенном ниже коде это должно заменить символ, указанный подчеркиванием, но это не так. Я посмотрел документацию для.each_char и.gsub, и эта комбинация должна работать. Почему этот фрагмент кода не работает?

string = "string"
new_string =string.each_char do |char|
  if char == "i"
    string.gsub(/char/,"_")
  end
end

ставит новую строку

Приведенный выше код должен вывести "str_ing". Правильно?

2 ответа

Решение

Есть несколько вещей не так с кодом.

Сначала регулярное выражение /char/ ищет буквальные символы char, а не содержимое переменной. То, что вы, вероятно, хотите /#{char}/ который оценивает char и создает регулярное выражение с его содержимым.

Далее посмотрите на разницу между gsub а также gsub!, gsub, который вы используете, создает новую строку. Внутри вашего блока вы создаете новую строку, но потом ничего не делаете с ней. Это в основном выбрасывается.

each_char Метод возвращает исходную строку после передачи каждого символа в блок. Строка не изменяется в блоке, поэтому в конце она не изменяется. Если вы использовали gsub! вместо gsub вы увидите то, что ожидали, поскольку исходная строка изменена.

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

В этом случае вы можете просто использовать gsub! сам по себе:

new_string.gsub!(/i/, '_')

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

string = "string"
string.each_char do |char|
  if char == "i"
    new_string = string.gsub(/#{char}/,"_")
  end
end
Другие вопросы по тегам