Разрыв длинных строк на нескольких строках в Ruby без снятия новых строк

Мы недавно решили на моей работе использовать руководство по рубиновому стилю. Одним из указов является то, что ни одна строка не должна быть шире, чем 80 символов. Поскольку это проект Rails, у нас часто бывают строки, которые немного длиннее - то есть " Пользователь X хотел отправить вам сообщение о Thing Y ", которое не всегда укладывается в ограничение в 80 символов.

Я понимаю, что есть три способа иметь длинную строку, охватывающую несколько строк:

  • Heredoc
  • % Q {}
  • Фактическая конкатенация строк.

Тем не менее, все эти случаи в конечном итоге занимают больше вычислительных циклов, что кажется глупым. Конкатенация строк, очевидно, но для HEREDOC и %Q я должен удалить символы новой строки, например .gsub(/\n$/, '').

Есть ли чистый синтаксический способ сделать это, что эквивалентно наличию всей строки в одной строке? Очевидно, что цель состоит в том, чтобы не тратить лишних циклов только потому, что я хочу, чтобы мой код был немного более читабельным. (Да, я понимаю, что вы должны сделать этот компромисс много... но для длины строки это просто кажется глупым.)

Обновление: обратная косая черта не совсем то, что я хочу, потому что вы теряете отступы, что действительно влияет на стиль/читабельность.

Пример:

if foo
  string = "this is a \  
string that spans lines"  
end

Я нахожу вышеупомянутое немного трудным для чтения.

РЕДАКТИРОВАТЬ: я добавил ответ ниже; три года спустя у нас теперь волнистый наследственный синдром.

Ответ 1

Спустя три года в Ruby 2.3 есть решение: Squiggly 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

Ссылка на сообщение в блоге: https://infinum.co/the-capsized-eight/articles/multiline-strings-ruby-2-3-0-the-squiggly-heredoc

Отступ строки с наименьшим отступом будет удаляется из каждой строки содержимого.

Ответ 2

Возможно, это то, что вы ищете?

string = "line #1"\
         "line #2"\
         "line #3"

p string # => "line #1line #2line #3"

Ответ 3

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

string = "this is a \
string that spans lines"

puts string.inspect

выведет "this is a string that spans lines"

Ответ 4

У меня была эта проблема, когда я пытаюсь написать очень длинный URL, работает следующее.

image_url = %w(
    http://minio.127.0.0.1.xip.io:9000/
    bucket29/docs/b7cfab0e-0119-452c-b262-1b78e3fccf38/
    28ed3774-b234-4de2-9a11-7d657707f79c?
    X-Amz-Algorithm=AWS4-HMAC-SHA256&
    X-Amz-Credential=ABABABABABABABABA
    %2Fus-east-1%2Fs3%2Faws4_request&
    X-Amz-Date=20170702T000940Z&
    X-Amz-Expires=3600&X-Amz-SignedHeaders=host&
    X-Amz-Signature=ABABABABABABABABABABAB
    ABABABABABABABABABABABABABABABABABABA
).join

Обратите внимание, что при формировании строки URL не должно быть никаких новых строк, пробелов. Если вам нужны переводы строки, используйте HEREDOC.

Здесь у вас есть отступ для удобства чтения, простоты модификации, без лишних кавычек и обратной косой черты в каждой строке. Стоимость соединения строк должна быть незначительной.

Ответ 5

Я изменил ответ Zack, так как я требуемые пробелы и интерполяция, но не символы новой строки и использовал:

%W[
  It a nice day "#{name}"
  for a walk!
].join(' ')

где name = 'fred' получается It a nice day "fred" for a walk!