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に挑戦したお話はこちらからどうぞ。
コメント