Чистый способ создания длинных строк в Ruby

При написании Ruby (клиентских скриптов) я вижу три способа создания более длинных строк, включая окончания строк, и все они «пахнут» для меня отталкивающе.

Есть ли более чистые и приятные способы?

Приращение переменной.

if render_quote?
  quote =  "Now that there is the Tec-9, a crappy spray gun from South Miami."
  quote += "This gun is advertised as the most popular gun in American crime. Do you believe that shit?"
  quote += "It actually says that in the little book that comes with it: the most popular gun in American crime."
  quote += "Like they're actually proud of that shit."
  puts quote
end

Heredocs (и незакрытые кавычки).

if render_quote?
  quote =<<EOS
Now that there is the Tec-9, a crappy spray gun from South Miami.
This gun is advertised as the most popular gun in American crime. Do you believe that shit?
It actually says that in the little book that comes with it: the most popular gun in American crime.
Like they're actually proud of that shit.
EOS

  puts quote
end

Или, просто не добавляя закрывающий тег:

if render_quote?
  quote = "Now that there is the Tec-9, a crappy spray gun from South Miami.
This gun is advertised as the most popular gun in American crime. Do you believe that shit?
It actually says that in the little book that comes with it: the most popular gun in American crime.
Like they're actually proud of that shit."

  puts quote
end

Или, при желании, с помощью gsub для исправления идентификации-вопросы (юк!?).

Объединение.

if render_quote?
  quote =  "Now that there is the Tec-9, a crappy spray gun from South Miami."
  quote += "This gun is advertised as the most popular gun in American crime. Do you believe that shit?"
  quote += "It actually says that in the little book that comes with it: the most popular gun in American crime."
  quote += "Like they're actually proud of that shit."
  puts quote
end

(цитата из Сэмюэля Л. Ипсума)

Я знаю, что наличие таких строк (т.е. логики представления) в моих сценариях само по себе является запахом, но я не знаю шаблона (кроме po-файлов или около того), чтобы очистить это.


person berkes    schedule 13.11.2012    source источник
comment
Чем ваша конкатенация отличается от приращения переменных? Вы дважды перечислили одно и то же?   -  person Sergio Tulentsev    schedule 13.11.2012
comment
@SergioTulentsev это выдуманное мной имя :). Поскольку foo++ и foo+= являются добавочным обновлением var. Вы делаете примерно то же самое здесь.   -  person berkes    schedule 13.11.2012


Ответы (3)


Обратите внимание, что соседние строковые литералы объединяются. Вы можете комбинировать это с символом продолжения строки \.

if render_quote?
  quote =
  "Now that there is the Tec-9, a crappy spray gun from South Miami. " \
  "This gun is advertised as the most popular gun in American crime. " \
  "Do you believe that shit?" \
  "It actually says that in the little book that comes with it: " \
  "the most popular gun in American crime. " \
  "Like they're actually proud of that shit."
  puts quote
end
person sawa    schedule 13.11.2012
comment
Не уверен, почему вы просто не удалили бы кавычки до самой последней и просто избежали бы возврата. У вас есть пробелы и кавычки в каждой строке, которые вам просто не нужны. - person vgoff; 13.11.2012
comment
@vgoff Я не знаю, что вы имеете в виду, когда говорите «избежать возврата». Я добавил пробелы после не последних строк, чтобы следующая строка не объединялась сразу после знака препинания. - person sawa; 13.11.2012
comment
Эта обратная косая черта является escape-символом, символ после него — возвратом. Таким образом, он избегает возврата. Если бы вы просто не поместили кавычку, оставили последний символ в строке и ввели обратную косую черту, то ввод был бы экранирован и не виден как часть строки. Это объясняет то, что я говорю? Таким образом, с экранированной новой строкой для Ruby это выглядит как набор строк, размещенных одновременно, с одним пробелом между строками. - person vgoff; 13.11.2012
comment
@vgoff Я понимаю, что ты имеешь в виду. Я не понял эту часть. Но тогда вы не сможете делать отступы строк без нежелательных пробелов. - person sawa; 13.11.2012
comment
Конечно, вы бы. Вы только избегаете возвращения... если это то, чего вы хотите. Если это не то, чего вы хотите, и вы хотите сохранить прибыль, сохраните ее. Причина, по которой вы используете их здесь, в основном состоит в том, чтобы сообщить Ruby, что вы еще не закончили задание. Так что это не имеет большого отношения к отступу. Именно поэтому я был несколько удивлен, что ответ был принят, если «чистое» условие было измерением. На данный момент вы в основном боретесь с Руби. - person vgoff; 13.11.2012
comment
@vgoff Удивляйся сколько хочешь. Мне все равно. - person sawa; 13.11.2012
comment
Смешной. Не имел в виду злого или плохого. Просто был удивлен. Я люблю сюрпризы. Это значит, что я чему-то научился. - person vgoff; 13.11.2012

После этого ваш код не работал у меня с тире ... но это работает, не требует дополнительного экранирования новых строк и просто говорит, что он делает в HereDoc.

if render_quote?
  quote = <<-EOS.strip.split.join(' ')
    Now that there is the Tec-9, a crappy spray gun from South Miami.
    This gun is advertised as the most popular gun in American crime. Do you believe that shit?
    It actually says that in the little book that comes with it: the most popular gun in American crime.
    Like they're actually proud of that shit.
  EOS

  puts quote
end

Тире перед EOS означает, что я смогу использовать EOS с отступом.

person vgoff    schedule 13.11.2012
comment
Если вы не используете полоску, она обеспечит наличие отступа, если вы этого хотите. Никаких дополнительных мест справа. Спасибо, Сава, что упомянул об этом. - person vgoff; 13.11.2012

Начиная с Ruby 2.3 у вас есть волнистый heredoc, чтобы избежать отступов в строке и по-прежнему сохранять отступы в вашем коде.

См. здесь для получения дополнительной информации.

Вот пример с той страницы.

class Subscription
  def warning_message
    <<~HEREDOC
      Subscription expiring soon!
      Your free trial will expire in #{days_until_expiration} days.
      Please update your billing information.
    HEREDOC
  end
end

Если вы не возражаете против отступов, вы также можете использовать синтаксис %Q{}, подобный этому, %Q дает замену строки, %q нет.

warning_message = %Q{
  Subscription expiring soon!
  Your free trial will expire in #{days_until_expiration} days.
  Please update your billing information.
}
person peter    schedule 06.11.2018