Rubyには4種類のヒアドキュメントがある。それぞれ見てみよう。なおヒアドキュメントの命名は著者による。
式展開ヒアドキュメント
恐らく最も基本的な、識別子に何も付けないヒアドキュメントである。 "
の文字列に相当し、式展開が行われることがポイント。
val = 123
str = <<EOS
hoge
piyo
fuga
#{val}
EOS
print str
hoge
piyo
fuga
123
式展開を行うことを明示する意味で、識別子を"
で囲っても同じ結果が得られるようになっている。
val = 123
str = <<"EOS"
hoge
piyo
fuga
#{val}
EOS
print str
hoge
piyo
fuga
123
非式展開ヒアドキュメント
'
の文字列に相当する、式展開を行わないヒアドキュメントもある。この場合はヒアドキュメントの識別子を'
で囲む。
val = 123
str = <<'EOS'
hoge
piyo
fuga
#{val}
EOS
print str
hoge
piyo
fuga
#{val}
コマンド出力ヒアドキュメント
これは少し変化球でコマンド出力リテラルに相当する、コマンド実行を行った結果を返すヒアドキュメントである。この場合はヒアドキュメントの識別子をバッククオートで囲む。
str = <<`EOS`
echo "What time is it now?"
date
EOS
print str
what time is it now?
Mon Aug 25 23:53:36 JST 2014
インデントヒアドキュメント
これは他のヒアドキュメントと組み合わせて使うことができる。識別子の前に-
をつけることで、終端の識別子をインデントすることができる。
begin
val = 123
str = <<-"EOS"
hoge
piyo
fuga
#{val}
EOS
end
print str
hoge
piyo
fuga
123
残念なのはヒアドキュメントの中身までインデントできるわけではないので、結局ヒアドキュメントの内部ではインデントが崩れてしまうことだ。
インデント崩れを解決する方法についてはおまけで述べる。
おまけ
ヒアドキュメントをメソッドの引数に使う
ヒアドキュメントの開始ラベルはRuby的には式にあたるため、式が書ける箇所にはヒアドキュメントの開始ラベルを書いて、続けてヒアドキュメントを書くことができる。
def method(*args)
p args
end
method('foo', <<EOS, 'baz')
bar
EOS
["foo", "bar\n", "bar"]
複数のヒアドキュメントを併用する
前項で書いたとおりヒアドキュメントの開始ラベルは式なので、複数のヒアドキュメントを1行に書いてしまうこともできる。
def method(*args)
p args
end
method(<<FOO, <<BAR, <<BAZ)
foo
FOO
bar
BAR
baz
BAZ
["foo\n", "bar\n", "baz\n"]
Ruby怖い。
ヒアドキュメント中のインデントを除去する
先ほどから度々書いているとおり、開始ラベルは式である。少し工夫して開始ラベルに文字列処理のメソッドを呼び出すことで、ヒアドキュメント中のインデントを除去することもできる。
以下はString#gsub
で行先頭の空白文字を除去することで、インデントを除去する例。
begin
str = <<-EOS.gsub(/^\s+/, '')
foo
bar
baz
EOS
end
print str
foo
bar
baz
これならインデントを崩さずにヒアドキュメントを使うことができる。
所感
無意識的に使っているが、こうして整理してみて勉強になった。