ヒアドキュメント / 複数行文字列 2015/04/22
改行を含むテキストをソースコードの中で普通に複数行で書いて、それを文字列として処理させる、各プログラミング言語ごとの方法のメモ。
ヒアドキュメントとか複数行文字列と呼んだりする。
改行だけでなくタブなど、普通であればエスケープ処理をしないといけないコントロール文字もそのまま書ける。
中に変数の参照を書くことにより普通の文字列リテラルと同様に変数展開される言語(Ruby, Perl, シェルスクリプトなど)もある。
C言語 C++ Java Scala Groovy PHP Python Ruby Perl sh JavaScript
C言語, C++ 2014/10/24
ない。と思っていたけど、C++11には Raw String Literal というのがあるらしい。
Java 2013/11/06
ない。
Scala 2015/04/22
ダブルクオーテーション3つ連続で複数行文字列を書くことができる。
エスケープ処理をせずに改行やダブルクオーテーションなどを含めることができる。ダブルクオーテーション3つ連続は、終端記号になってしまうので、ヒアドキュメントの中にダブルクオーテーション3つ連続は、たぶん含められない。
val str = """foo
bar""";
Groovy 2014/10/24
シングルクオーテーションまたはダブルクオーテーション3つ連続で複数行文字列を書くことができる。
シングルクオーテーション3つ連続とダブルクオーテーション3つ連続の両方が含まれる文字列はどうやって書くんだろう?
PHP 2016/08/15
例
$str = <<<EOS
foo
bar
EOS;
普通のヒアドキュメントとNowdocというものがある。ヒアドキュメントでは、"
で囲んだ文字列リテラルと同じように、$
で始まる部分が変数名としてその値に
インライン展開されるのに対して、
Nowdocは、'
で囲んだ文字列リテラルと同じように、そういった展開がされない。
NowdocはPHP5.3以降でのみ使える。
$greeting = "Hello";
// ヒアドキュメント
echo <<<EOS
$greeting, World!
EOS;
// => Hello, World!
// ヒアドキュメント
echo <<<"EOS"
$greeting, World!
EOS;
// => Hello, World!
// Nowdoc
echo <<<'EOS'
$greeting, World!
EOS;
// => $greeting, World!
ヒアドキュメント | PHP Manual
http://php.net/manual/ja/language.types.string.php#language.types.string.syntax.heredoc
Nowdoc | PHP Manual
http://php.net/manual/ja/language.types.string.php#language.types.string.syntax.nowdoc
Python 2015/04/22
三重引用符(トリプルクオート) '''
または """
で囲むと複数行文字列を書くことができる。
"""\
foo
bar
"""
上記の例で1行目にバックスラッシュがあるのは最初の改行を文字列に含めないようにするため。
Ruby 2014/03/19
例
str = <<EOS
foo
bar
EOS
クォーテーションで囲まないヒアドキュメントやダブルクオーテーションで囲んだヒアドキュメントは中の #{...}
の部分がインライン展開される。シングルクオーテーションで囲んだヒアドキュメントはインライン展開されない。
greeting = "Hello"
p <<EOS
#{greeting}, World!
EOS
# => "Hello, World!\n"
p <<"EOS"
#{greeting}, World!
EOS
# => "Hello, World!\n"
p <<'EOS'
#{greeting}, World!
EOS
# => "\#{greeting}, World!\n"
バッククオート(```)で囲むと、コマンドとして実行され、その結果を文字列として取得できる。コマンド実行前に #{...}
のインライン展開もされる。
command = 'date'
p <<`EOS`
#{command}
EOS
# => "Thu Mar 20 00:05:48 JST 2014\n"
複数のヒアドキュメントを1行で使うこともできる。
arr = [<<EOS, <<EOS]
aaa
EOS
bbb
EOS
p arr
# => ["aaa\n", "bbb\n"]
ヒアドキュメントは普通の文字列なので、その場でメソッドを呼び出すこともできる。
p <<EOS.length # => 8
foo
bar
EOS
<<
のあとに-
をつければ、終端の識別子の前にインデントを置くことができる。ただし、ヒアドキュメントの中身のインデントは文字列として含まれてしまう。
p <<-EOS
foo
bar
EOS
# => " foo\n bar\n"
Ruby 1.9.3 リファレンスマニュアル > ヒアドキュメント
http://doc.ruby-lang.org/ja/1.9.3/doc/spec=2fliteral.html#here
Perl 2016/05/05
変数展開されるヒアドキュメントの例
my $str = <<EOS;
aaa
bbb
EOS
my $str = <<"EOS";
aaa
bbb
EOS
変数展開されないヒアドキュメントの例
my $str = <<'EOS';
aaa
bbb
EOS
複数のヒアドキュメントを1行で使うこともできる。
my @arr = (<<EOS, <<EOS);
aaa
EOS
bbb
EOS
print @arr;
# =>
# aaa
# bbb
<<EOS
のEOS
の部分を終端識別子と言い、裸のままにするかダブルクオートで囲むと、普通のダブルクオートで囲んだ文字列と同様に中の変数名が展開される。シングルクオートで囲めば、普通のシングルクオートで囲んだ文字列と同様に変数名は展開されない。
ヒアドキュメントがファイルの最後まで続くからといって終端の識別子を省略すると、エラーになってしまう。
ファイルの最後にテキストデータを置きたい場合は、ヒアドキュメントの代わりに __DATA__
を使うとよい。
__DATA__
とだけ書いた行があると、そこでperlのソースコードが終了しているものとみなし、かつその次の行からは main::DATA
というファイルハンドルで読み出すことができる。
__DATA__
を使う例
print foreach (<main::DATA>);
__DATA__
Hello
World!
__DATA__
| perldoc.jp
http://perldoc.jp/docs/perl/5.18.1/perldata.pod#Special32Literals
sh (シェルスクリプト) 2016/05/05
例
cat <<EOD
foo
bar
$HOME
`date`
EOD
ヒアドキュメントの中では `
や $
で始まる変数の展開が使える。それらを使いたくない場合は、以下のように最初の終端識別子の前にバックスラッシュ \
を付ける。
cat <<\EOD
MacBookPro 13-inch: $1499
MacBookPro 15-inch: $1999
EOD
ヒアドキュメントがファイルの最後までの場合は、最後の終端識別子を省略できる。
ヒアドキュメントの後にパイプで別のコマンドを繋ぎたい場合、ヒアドキュメントの後ろではなく前に書く。
cat <<EOD | sed s/o/0/g
foo
bar
EOD
出力は
f00
bar
となる。
複数のヒアドキュメントを1行で使うこともできる。
cat <<EOS; cat <<EOS
aaa
EOS
bbb
EOS
出力は
aaa
bbb
となる。
スクリプトの見やすさのためにヒアドキュメントの部分もインデントしたい場合、普通にインデントするとインデント自体もヒアドキュメントに含まれてしまうし、
EOD
の終端子はインデントしたら終端子とみなしてくれないので、
if true; then
cat << EOD
Hello
EOD
fi
のよう残念な形になるし、以下のように出力自体にもインデントが含まれてしまう。
Hello
この場合 <<
の代わりに <<-
を使うとよい。ただしインデントはスペースではなくタブ限定である。
if true; then
cat <<- EOD
Hello
EOD
fi
出力は
Hello
となる。
JavaScript 2015/04/22
標準ではヒアドキュメントの仕組みはないが、似たようなことを実現する工夫はできるらしい。
Javascriptでヒアドキュメント | Miuran Business Systems
http://www.m-bsys.com/code/javascript-heredoc