或るプログラマの開発日記

日々の勉強したことの備忘録なんかに使っていきます

Rubyのヒアドキュメントを使ってみる

Rubyのヒアドキュメントに関するメモ。文字列を扱うちょっとしたプログラムで結構使えます。

ヒアドキュメントとは

普通の文字列リテラルはデリミタ(", ', ` など)で囲まれた 文字列ですが、ヒアドキュメントは `<<識別子' を含む行の次の行から `識別子' だけの行の直前までを文字列とする行指向のリテラルです。

https://docs.ruby-lang.org/ja/latest/doc/spec=2fliteral.html#here

ヒアドキュメントを使うメリットとして、

  • 複数行の文章を変数で扱う場合、コード上にそのまま記述可能。
  • ダブルコーテーション、シングルコーテーションを含む文字列もエスケープ無しで記述可能。

があります。

ヒアドキュメントの書き方

一口にヒアドキュメントといっても、色んな書き方があるのでまとめてみます。

基本

下の例はEOSを識別子としています。慣例的にEOSまたはEOFを使うことが多いようですが、開始と終了の識別子が合っていればなんでもかまいません。

puts <<EOS
"Hello World!"
EOS
#=>"Hello World!"
式展開

ヒアドキュメントは、通常の文字列と同じく式展開が可能です。シングルコーテーションで開始の識別子を囲むと式展開はされません。

name = "Taro"
puts <<"STR1"
Hello! #{name}
STR1
#=>Hello! Taro

puts <<'STR2'
Hello! #{name}
STR2
#=>Hello! #{name}
インデント

通常は終了の識別子を行頭に書かないとエラーになりますが、識別子の前にハイフンをつけると、終了の識別子をインデントできます。

3.times do
  puts <<-EOS
    Hello World!
  EOS
end
#=>    Hello World!
#=>    Hello World!
#=>    Hello World!

但し、上の例では余計なインデントがヒアドキュメントに含まれてしまいます。Ruby2.3以降ではチルダをつけることで、余計なインデントを除去してくれます。

3.times do
  puts <<~EOS
    Hello World!
  EOS
end
#=>Hello World!
#=>Hello World!
#=>Hello World!
コマンド実行

以下のように書くことでコマンド実行ができます。Windowsで動作確認済み。

puts <<`ENV`
env 
ENV

SQLなんかを扱うのに便利

個人的に良く使う例として、SQLのようなダブルコーテーション、シングルコーテーションがある文字列を扱うのに便利なので、複数のinsert文やselect文を生成したい時に使います。

s =<<STR1
0001
0002
0003
0004
0005
STR1
s.split.each do |str1|
  [1,2].each do|num1|
    puts <<~SQL
      select * from table where col1 = "#{str1}" and col2 = #{num1};"
    SQL
  end
end

実行結果

select * from table where col1 = "0001" and col2 = 1;"
select * from table where col1 = "0001" and col2 = 2;"
select * from table where col1 = "0002" and col2 = 1;"
select * from table where col1 = "0002" and col2 = 2;"
select * from table where col1 = "0003" and col2 = 1;"
select * from table where col1 = "0003" and col2 = 2;"
select * from table where col1 = "0004" and col2 = 1;"
select * from table where col1 = "0004" and col2 = 2;"
select * from table where col1 = "0005" and col2 = 1;"
select * from table where col1 = "0005" and col2 = 2;"