【Rubyメモ】ヒアドキュメントについて理解する!こつこつ学んでいこう!

IT/プログラミング

Ruby(ver 2.1の範囲)を勉強していると
ヒアドキュメントというワードに
遭遇しました。

実業務ではあまり
使われなさそうな気もしますが、
ちょっと調べてみることにしました。

まずは英語の意味を調べます

ヒアドキュメントは、「here document」とそのままですかね。
1つ1つだと以下でしょうか。

here:「ここ、ここで、ここやで!」
document:「文章、資料、記録」

「ここは文章ですよ!」ってことですね。

ヒアドキュメントを使うシーン

改行を伴う文章をつかうときに、
バックスラッシュを利用すれば書く事は可能なのですが、
可読性が悪くなるそうです。読みにくくなるってことですね。

ヒアドキュメントを使えば、バックスラッシュなど使わずに
改行を伴う文章を利用することができます。

ヒアドキュメントの例

ヒアドキュメントの簡単な例は以下です。

test = <<TEST
あいうえお
かきくけこ
TEST

p test
実行結果:"あいうえお\nかきくけこ\n"

ヒアドキュメントにはルールがあります。
「<<」の後に識別子を任意でつけます。
「<<TEST」
そして、終端を示す識別子は、
最初に定義した「<<TEST」の「TEST」です。
ヒアドキュメントの最後に「TEST」を記載します。

これで動きます。

ヒアドキュメントの注意点1

以下のケースだとエラーになります。

test = << TEST
あいうえお
かきくけこ
TEST

p test
実行結果:syntax error, unexpected <<
test = << TEST

なぜエラーになったかというと、
「構文エラー、予期しない<<」と言っています。

「<<」と「TEST」の間に半角スペースが存在するからです。

これで動きます。

ヒアドキュメントの注意点2

以下のケースもエラーになります。

test = <<TEST
あいうえお
かきくけこ
 TEST

p test
実行結果:can't find string "TEST" anywhere before EOF

これはなぜエラーになったかというと、
「EOFの前のどこにも文字列”TEST”が見つかりません」と言っています。

※EOFはend of file。つまり、ファイルの最後って意味ですかね。
なぜ見つからないかというと、
終端の識別子の前に半角スペースが存在するからです。

終端の識別子には「行頭に書く」というルールが存在します。


ただし、以下の方法を利用すると、
エラーにならずに実行できます。

test = <<-TEST
あいうえお
かきくけこ
 TEST

p test
実行結果:"あいうえお\nかきくけこ\n"

識別子を「<<-TEST」と記載するとエラーにはなりません。
「<<」と「TEST」の間に「-(ハイフン)」を入れると、
最後の行頭にスペースが入っている識別子を書いても問題ないのです。
ややこしい笑

ヒアドキュメントの注意点3

以下の方法を使うとヒアドキュメントのなかで式を展開できます。

word = "さしすせそ"
test = <<"HERE_DOCUMENT"
    あいうえお
    かきくけこ
    #{word}
HERE_DOCUMENT

p test
実行結果:"    あいうえお\n    かきくけこ\n    さしすせそ\n"

なぜ式を展開できたかというと、
識別子の定義をダブルクォートで囲ったからです。「”HERE_DOCUMENT”」
覚えておきましょう!

終端の識別子をダブルクォートで囲ったらどうなるの?
と思う方もいるでしょう。私です。
やってみました!

word = "さしすせそ"
test = <<"HERE_DOCUMENT"
    あいうえお
    かきくけこ
    #{word}
"HERE_DOCUMENT"

p test
実行結果: can't find string "HERE_DOCUMENT" anywhere before EOF

はい、エラーとなりました。
「終端の識別子が見つからないでござる!」
と言われております。想像の通りでした。

ヒアドキュメントの注意点4

識別子をダブルクォートで囲いましたが、シングルクォートだと以下になります。

word = "さしすせそ"
test = <<'HERE_DOCUMENT'
    あいうえお
    かきくけこ
    #{word}
HERE_DOCUMENT

p test
実行結果:"    あいうえお\n    かきくけこ\n    \#{word}\n"

出力はされますが、式展開はされませんでした。
覚えておきましょう!

・・・試してみたいですか?
結果はもうわかると思いますが、お約束は以下です。

word = "さしすせそ"
test = <<'HERE_DOCUMENT'
    あいうえお
    かきくけこ
    #{word}
'HERE_DOCUMENT'

p test
実行結果: can't find string "HERE_DOCUMENT" anywhere before EOF

・・・・・はい。

ヒアドキュメントの注意点5

識別子を「<<-“任意の識別子”」でやってみました。

word = "さしすせそ"
test = <<-"HERE_DOCUMENT"
    あいうえお
    かきくけこ
    #{word}
     HERE_DOCUMENT

p test
実行結果:"    あいうえお\n    かきくけこ\n    さしすせそ\n"

はい!式展開されて、
終端の識別子もspaceがあっても
エラーになりませんでしたね!

色々とやってみた

式展開のなかに終端の識別子を入れてみました。

word = "HERE_DOCUMENT"
test = <<-"HERE_DOCUMENT"
    あいうえお
    かきくけこ
    #{word}
     HERE_DOCUMENT

p test
実行結果:"    あいうえお\n    かきくけこ\n    HERE_DOCUMENT\n"

式展開された識別子には影響されませんでした!

次です!

word = "HERE_DOCUMENT"
test = <<-"HERE_DOCUMENT"
    あいうえお
    かきくけこ
    #{word}
     'HERE_DOCUMENT'
     HERE_DOCUMENT

p test
実行結果:"    あいうえお\n    かきくけこ\n    HERE_DOCUMENT\n     'HERE_DOCUMENT'\n"

最後の識別子で判定されました!

お次はお次は!

word = "HERE_DOCUMENT"
test = <<-"HERE_DOCUMENT"
    あいうえお
    かきくけこ
    #{word}
     HERE_DOCUMENT
     'HERE_DOCUMENT'

p test
実行結果:"    あいうえお\n    かきくけこ\n    HERE_DOCUMENT\n"

「#{word}」の下の識別子が終端となります。
その下の「’HERE_DOCUMENT’」は見事にスルーしました。
エラーにもなりませんでしたね。

まとめ

  • 先頭の識別子が「<<任意の識別子」の場合、終端は「行頭に識別子」を書く。
  • 先頭の識別子が「<<“任意の識別子”」の場合、式展開できる。
  • 先頭の識別子が「<<-“任意の識別子”」の場合、式展開できるし、終端は行頭以外でOK
  • 先頭の識別子が「<<‘任意の識別子’」の場合、式展開できないでござる。

以上、ヒアドキュメントのお勉強でした~

RubySilverに挑戦した

Ruby Silverに挑戦したお話はこちらからどうぞ

コメント

タイトルとURLをコピーしました