改行を削除せずにRubyで複数行の長い文字列を分割する


221

私は最近、私の仕事でルビースタイルガイドに決めました。禁忌の1つは、どの行も80文字を超えてはならないということです。これはRailsプロジェクトであるため、文字列が少し長くなることがよくあります。つまり、「ユーザーXがThing Yについてのメッセージを送信したかった」というもので、常に80文字のスタイル制限に収まりません。

長い文字列を複数行に分割するには3つの方法があることを理解しています。

  • HEREDOC
  • %Q {}
  • 実際の文字列連結。

ただし、これらすべてのケースで、より多くの計算サイクルが必要になり、ばかげているように見えます。文字列の連結は当然ですが、改行を取り除かなければHEREDOCなり%Qません.gsub(/\n$/, '')

これを行うための純粋な構文方法はありますか?これは、文字列全体を1行に収めるのと同じです?目標は、明らかに、コードをもう少し読みやすくするために余分なサイクルを費やさないことです。(はい、私はあなたがそのトレードオフをたくさんしなければならないことを理解しています...しかし、文字列の長さのために、これはばかげているように見えるだけです。)

更新:インデントがなくなるため、バックスラッシュは私が望んでいるものとは異なります。インデントはスタイル/読みやすさに影響を与えます。

例:

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

上記は少し読みにくいです。

編集:私は以下の回答を追加しました。3年後、波状のヒアドキュメントができました。


これらの文字列を除外することは、あなたの価値があるかもしれません。
Cheezmeister 2013


new \n改行文字を保持するかどうかは不明です。一番上の答えはそれらを保持しません—しかし、あなたの答えは保持します。質問には「改行を削除せずに」と書かれていますが、説明には「[...]改行を削除する必要があります」と書かれています。
ブライアンディマス2017

回答:


432

多分これはあなたが探しているものですか?

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

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

4
ええと。ええ、それはかなり完璧です。それは実際にフードの下で連結を行うことですか?(+?を非表示)
chug2k 2012年

13
そうではないと私はかなり確信しています。String#+の定義解除と再定義の両方を試みましたが、何も送信されていないようです。
Jessehz、2012年

また、文字列を同じ行に並べて配置することもできますが、あまり役に立ちません。
Jessehz

3
エミリーのソリューションも気に入っています。しかし、何らかの理由で、次の行の先頭の空白は、自分で推測することなくインデントできるため、この方が快適です。
アミンAriana

5
再度連結して、この関連する質問に対するAmadanの回答を確認してください。彼はバイトコードを使用して、文字列を連結するのではなく、1つの長い文字列として扱うことを証明します。
トムハント2017年

55

\Rubyの任意の行が次の行に続くことを示すために使用できます。これは文字列でも機能します:

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

puts string.inspect

出力されます "this is a string that spans lines"


11
ええと。それはかなり簡単です。まあ、それはおそらく質問するには多すぎますが、次の行をインデントすることはできません。等号と一致させることができれば理想的です。
chug2k

5
注:バックスラッシュの後に空白を入れることはできません。最後の文字でなければなりません。
Julian Mann

3
@Jessehzの回答をご覧ください。適切なインデントを使用して適切にフォーマットされたコードを作成する方法は、各行を引用符で囲むことです。
orrd

36

3年後、Ruby 2.3にソリューションがあります:波状のヒアドキュメント。

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

最もインデントされていない行のインデントは、コンテンツの各行から削除されます。


29
疑問に思う他の人のために:<<~HEREDOC改行文字を保持し、インデントのみを取り除きます。例line 1\nline 2\nline 3\n
ブライアンディマス2017

1
ただし、改行を削除しても追加の計算が必要になりますが、これは暗黙のOPソートでは望ましくありません。
henrebotha 2017年

1
@henrebothaはい、しかしOPは、「文字列全体を1行に収めるのと同じこと」をより明確に望んでいると述べ、改行は不要です。
Nick

したがって、ヒアドキュメントを使用したくなく、改行を削除する必要があることを質問で明示的に述べました。ここでの答えは、ヒアドキュメントを使用しており、回避したい「後処理」が必要です。
ラモント

17

非常に長い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を使用してください。

ここには、読みやすさ、変更のしやすさのためにインデントがあり、すべての行に手間のかかる引用符やバックスラッシュがありません。文字列を結合するコストはごくわずかです。


10

スペースと補間は必要だが改行は必要ないため、ザックの回答を変更して使用しました。

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

name = 'fred'これが生成する場所It's a nice day "fred" for a walk!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.