ヒアドキュメント

昨日の日記で「後述」と書いておきながら、忘れていました。(^_^;)
「ヒアドキュメント」(Here Document)は、複数行のリテラルな文字列をコード中に埋め込むのに良く使われる構文です。「リテラルな文字列」というと普通は「"」(ダブルクォート)や「'」(シングルクォート)などの「クォート文字」で挟む事で記述しますが*1、ヒアドキュメントでは文字ではなく「クォート行」になります。
「<<識別子」がヒアドキュメントです。その次の行から文字列が始まって、「識別子」だけの1行を見つけたら、そこまでが文字列になります。

use strict;
 
my $string = <<EOT;
aaa
bbb
ccc
EOT
 
print $string;

識別子に「EOT」を使っています。ヒアドキュメントの識別子は大文字を使うのが慣習のようです。「my $string = <<EOT;」の行と「EOT」の行の間が文字列です。「EOT」の行は、識別子以外のスペースやコンマを入れてはいけないので注意が必要です。
実行結果は以下の通りです。

aaa
bbb
ccc

$string には "aaa\nbbb\nccc\n" という文字列が入っている事になります。これは、以下のように書いたのと同じ意味です。

use strict;
 
my $string = "aaa
bbb
ccc
";
 
print $string;

実行結果は最初のコードと同じになります。つまり、ヒアドキュメントは「<<識別子」の部分に、次の行から識別子の行までの文字列を「埋め込んでいる」というわけですね。ヒアドキュメントの「Here」(ここ)は、「ここに入る」という意味でしょうか。


今のように、ただ代入するだけなら普通のクォートと大きな違いはありませんが、例えば「複数行のリテラル文字列に対して正規表現マッチングを行なった結果を代入したい」という場合は、俄然変わってきます。
INI ファイル形式の複数行リテラル文字列をハッシュに変換したい場合、普通のクォートによる埋め込みではこうなります。

my %values = "name=Palmo
lang=Perl
hobby=programming
" =~ m/^([^=]+)=(.+)$/mg;

処理と処理の間に文字列が挟まっていて、とても読みづらいです。代入の行とマッチングの行が一致していないだけでも読みづらいのに、マッチングは文字列が終わらないと登場しません。これでは見落としてしまいそうですし、どこからどこまでが文字列で、どこからがコードなのかも瞬時には判断できませんね。(^_^;)
対して、これをヒアドキュメントで書くとこうなります。

my %values = <<INI =~ m/^([^=]+)=(.+)$/mg;
name=Palmo
lang=Perl
hobby=programming
INI

「<<INI」の部分に文字列が埋め込まれるので、「<<INI」に対してマッチした結果を %values に代入しています。
「処理は処理」「文字列は文字列」と、くっきりかっきり別れていて、何をしようとしているのかが一目瞭然ですね。(^_^) こちらの方が読みやすいと思います。


また、ヒアドキュメントに使う識別子は「クォート」で囲む事ができます。「"」(ダブルクォート)で囲むと、文字列の中の変数が展開されます。「'」(シングルクォート)なら、変数は展開されません。クォートを省略した場合は「"」(ダブルクォート)で囲んだのと同じ意味です。

use strict;
my $name = "Palmo";
 
print <<"EOT";
$name the Perl Student
EOT
 
print <<'EOT';
$name the Perl Student
EOT
 

最後の改行は必須です。EOTの後に改行がないと、エラーになります。恐らく Perl はヒアドキュメントの文字列の終端行として「\n識別子\n」を探しているのではないでしょうか。
実行すると以下のようになります。

Palmo the Perl Student
$name the Perl Student

「"」(ダブルクォート)の方は展開されて、「'」(シングルクォート)の方は展開されませんでした。(^_^)

*1:qやqqを使うとクォート文字を変えられるのでしたね