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

182

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

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

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

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

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

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

Пример:

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

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

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

  • 0
    Это может стоить вашего времени, чтобы выделить эти строки.
Показать ещё 1 комментарий
Теги:

5 ответов

31
Лучший ответ

Спустя три года в 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

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

  • 14
    Для всех, кто интересуется: <<~HEREDOC сохраняет символы новой строки, он только лишает отступа. Например, line 1\nline 2\nline 3\n
  • 0
    Удаление новых строк все равно потребует дополнительных вычислений, что, как подразумевает OP, нежелательно.
344

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

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

p string # => "line #1line #2line #3"
  • 3
    да. да, это довольно прекрасно это на самом деле делает сцепление под капотом? (скрывая +?)
  • 11
    Я вполне уверен, что это не так; Я пробовал как undef'ing, так и переопределить String # +, и не похоже, что туда что-то отправляют.
Показать ещё 3 комментария
46

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

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

puts string.inspect

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

  • 10
    да. это довольно просто. ну, это, наверное, слишком много, чтобы спросить, но я не могу отступить от следующей строки. было бы идеально, если бы я мог сопоставить его со знаком равенства.
  • 4
    Примечание: после этой обратной косой черты не должно быть пробелов. Это должен быть последний символ.
Показать ещё 1 комментарий
13

У меня была эта проблема, когда я пытаюсь написать очень длинный 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.

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

6

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню