Rubyのヒアドキュメントの基本というか私の使い方。

結論

「~EOS」を使えば終端EOSが左端になくていい。最初の文字列を基準にしてインデントがその通りに出力される。

そもそも基本、終端EOSは左端にないといけないってルールを知らないといけない?「インデントとかこっちの考え、意図を汲み取ってそっち(Ruby)で勝手にやってほしい!」とかは全然汲み取ってもらえない、通用しない。

↓これが私の正解。「~EOS」を使って書きたい通りに書く。

if true
  strs = <<~EOS
    <html>
      <head>
      </head>
      <body>
      </body>
    </html>
  EOS
end

puts strs

少なくとも私がやりたいことに対しては万能。「~EOS」で解決。

  1. ヒアドキュメントが左端から浮くようなら、終端EOSが左端から浮くようなら「-EOS」「~EOS」。
  2. 行頭のスペースを削除したいなら「~EOS」。
  3. 結局、「~EOS」だけで対応可。

ヒアドキュメントとは

ヒアドキュメントはまとまった複数行の文字列を書くのに向いています。文字列を複数行に渡って表示したい、変数に定義したい、そんなときありますよね。

基本的にはダブルクオーテーション扱いです。
あとテッパンって形があるので覚えましょう、またはすぐアクセス(すぐ検索して情報にアクセスできること)できるようにしましょう。

ダブルクオーテーション相当だけど、文字列中の「”」はエスケープしなくてもいいみたいです。ついでに式展開も行われます。ついでって…。

覚えたら一番速い!でも辞書が引ければ通用する。大事なのは記憶でも辞書でも「何を調べればいいか」がまず頭に出てこないといけない。要はトリガーを用意しとけってことだね。

鉄板型はこう。

strs = <<EOS
文字列1
文字列2
文字列3
EOS

puts strs

EOSに「””」をつけて「”EOS”」でもいいみたいだけど、いまの自分のやりたいことに対しては覚える必要なし!

↓これは覚えなくていい

strs = <<"EOS"
文字列1
文字列2
文字列3
EOS

puts strs

ちなみに文字列をインデントしようとすると出力にも行頭にスペースが入る(からダサい)。なんでインデントするの?→見やすくするため。

strs = <<EOS
  文字列1
  文字列2
  文字列3
EOS

puts strs

プログラムがエディターの左寄せ以外にもインデントを使ってプログラムを見やすく書くことがある。その場合、下記ではエラーになる。

if true
  strs = <<EOS
  文字列1
  文字列2
  文字列3
  EOS
end

puts strs

ちなみにこれならOK。でもダサいよね?上との違いはEOSが左端に寄っている。

if true
strs = <<EOS
文字列1
文字列2
文字列3
EOS
end

これでもOK。

if true
  strs = <<EOS
  文字列1
  文字列2
  文字列3
EOS
end

とにかく終端EOSが左端にあればOK。

終端のEOSがインデントされる場合

「終端の識別子をインデントしたい、または普通に見やすく書こうとしたらそうなる」場合、「<<-EOS」にする必要がある。「-」を付けます。

if true
  strs = <<-EOS
  文字列1
  文字列2
  文字列3
  EOS
end

puts strs

「EOSがとにかく左端から浮いてしまうなら-を付けます。」

でも…これをputsしたりファイルに出力すると各文字列の行頭にインデント分のスペースが入ってしまいます。出力したものの行頭にスペースがあるとダサい(場合がある)。

「~」を使え!

ほんとすいません!私、プログラマーになりたいわけじゃないんです。なので使い方や理解が間違っているかもしれません。

結局、私が「いまのところ」したいことに対してのヒアドキュメントって2パターンに分かれることになりました。
「普通のEOS」と「~EOS」

そのうち1つは大は小を兼ねているので、それで書けるように覚えるのは1つになりました。エントリー者が混乱するとプログラミングが面白くないんです。ごめんなさい。

いまのところ私がヒアドキュメントを使っているのはHTMLのタグ生成やテキスト出力に使っています。だからインデントは結構ちゃんとしたいんです。(ちゃんと!ってちょっと前に言ったことと矛盾してる…?)「表示だけは」ちゃんとしたいんです。

いままで出てきたのは「普通のEOS」と「-EOS」の2つ。

この「<<~EOS」を使うと終端識別子のインデントと行頭の無駄なスペース問題が解決されます。

if true
  strs = <<~EOS
    <html>
      <head>
        <p>
      </body>
    </html>
  EOS
end

puts strs

一番上の「<html>」を基準として複数行の文字列はインデントされます。

再確認

ただいま、いろいろと切り分けてみましたが、結局は終端のEOSをどうしたいか、またはどうなっているかでした。他がインデントしていてもEOSがエディター左寄せなら「普通のEOS」でOKです。でも見た目がなんかダサい、っていう場合があります。だから、私がやりたいことに関してはいまのところ「~EOS」一択なのかなと思っています。

例えばこんなヒアドキュメント。

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport">
    <title>web_title</title>
    <link rel="stylesheet">
    <script src="https://"></script>
    <script src="https://"></script>
    <script src="https://"></script>
  </head>
  <body>
    <h2>midasi</h2>
    <p>abcxyz</p>
  </body>
</html>

そう、HTMLの記述です。

このヒアドキュメントをRubyプログラムのどこで書くかが分かれ道ということです。ただの変数定義なら(「ただの」って意味がわからないですが笑)問題ありません。エディタ左寄せでこう書けばOKです。

html = <<EOS
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    ~
    ~
EOS

puts html

でもプログラムってif文やeach文、「open() do end」の中で書くことありますよね?そのときインデントしますよね?

if ture
  html = <<EOS
  <!doctype html>
  <html>
    <head>
      <meta charset="utf-8">
EOS
end

puts html

こうやっちゃうと終端EOSは正しいけど、こいつだけインデントされていないから見た目が変。あと出力したテキストは見たまんますべてにスペースが付いている。だからなんかダサい。

結果から考える

出力テキストはこうなればいい。
まずはゴールを示そう!

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    ~
    ~
    ~
</html>

「<<~EOS」を使えばOK!!

if true
  html = <<~EOS
  <!doctype html>
  <html>
    <head>
      <meta charset="utf-8">
      ~
      ~
      ~
  </html>
  EOS
end

puts html

ってことはやっぱり私がやりたいことに関しては「= <<~EOS」が最強ってことです。最強の意味がわかりませんが、これだけでやりたいことができるっちゅうことです。雑ですいません。

  • EOSが浮いているなら必ず「-」「~」が必要。
  • インデントは最初の行を基準にして行われる。
  • 先頭スペースがダサいなら「<<~EOS」で解決。

一度使ったものは出来るだけ忘れないようにするか、またはすぐアクセスできるようにする。したい。Rubyメソッドやしくみ、文法など。

スポンサーリンク
投稿記事
スポンサーリンク
OKE2GOU