ナンモワカランアザラシ

技術的なアレコレを自分の言葉で書いて保管・公開しておくための静かなインターネット

ヒアドキュメントって何

なんか<<EOFとかやると複数行の文字列をスクリプト内に埋め込めるやつ、という認識である。 最近、terraformでヒアドキュメントを使って複数行にわたる文字列をパラメータや変数に渡すことが多い。これを機に調べる。

このあたりを理解したい。

概要を理解したい

ヒアドキュメントの厳密な定義や宣言があって、それをもとに各言語で実装されているものだと思い込んでいたが、どうやら違うらしいことが分かってきた。

一次情報に近そうなドキュメントを探したが見つからなかった。 個人ブログかwikipedia、あるいは世界の辞書的なサイトになろうとしているページしか見つからない。 あまり自明な概念ではないと思う。みんなが勝手に合意をしているものなのだろう。

https://en.wikipedia.org/wiki/Here_document この手の話題には珍しくwikipediaを参照させてもらう。それくらい、参考ドキュメントの発掘に困っている。

「あたかも別ファイルかのように扱える、ソースコード内の一部」だそうだ。 まあ単純に「複数行の文字列入力ができる書き方」という理解であまり間違ってなさそうに思える。

Unixシェルが起源であるという記述が複数見つかるが、信用にたるドキュメントは見つからない。

言語ごとの使われ方を知りたい

bash

https://www.gnu.org/software/bash/manual/bash.html#Here-Documents

The format of here-documents is:

[n]<<[-]word
        here-document
delimiter

最初のwordをクオートすると、here-document部分の変数が展開されないそうだ。へぇ。

他の言語でもおおむね同じっぽい。jsでは同じような概念でテンプレートリテラルがES6から導入されている。 jsに慣れている私としては、最初から「テンプレートリテラルみたいなものだよ」って説明してくれればスッと理解できたのに...。

終端識別子、自由過ぎない?

<<EOFEOF部分を何て呼ぶかが分からなかったのでChat GPTに聞いた。呼び方があっているのかは分からない。 スクリプト内で一意であればよいらしいが、あまりにも自由すぎやしないだろうか...。この自由さが、最初の理解を阻んでいた気がする。 人によってEOFEOLEOTにしているのを見る。"Enf Of File"とかそういうところから来ているのだろう。

終端識別子が自由な理由は考えてみれば明快だった。 終端識別子自体をヒアドキュメントに含められないからだ。

エスケープすればいいじゃんとなるが、特定文字だけエスケープが必要だと、「スクリプト内であたかも別ファイルかのように扱う」のニュアンスが薄れてしまうだろう。