Search

検索したいワードを入力してください

2019年04月04日

Rubyのヒアドキュメントの基本と使い方を理解する

Rubyでヒアドキュメントを使ったことがあるでしょうか。普段ファイルなどでコマンドラインに情報を渡している部分をヒアドキュメントに変えると、臨機応変なコード記述が可能になります。本記事を参考に、Rubyでヒアドキュメントを使ってみましょう。

ヒアドキュメントとは

コマンドを実行する時に、引数としてコマンド内で使用する値などをファイルとして渡すことがあります。外部から与えられたデータのまとまりを使って処理を行うコマンドを、シェルから呼ぶ際に、ファイル引数としてではなく、直接データのまとまりを記述して与えることができます。

直接コマンドラインにデータを与える方法が「ヒアドキュメント」で、ヒアドキュメントの書き方は、使用する言語やシェルによって異なります。

ヒアドキュメント例

Linuxコマンドのヒアドキュメントを例に挙げてみましょう。以下のコードをターミナルで実行するとヒアドキュメントというものが理解できます。以下の例では、「EOF」が現れるまでのテキスト内容を「test」ファイルに出力します。

【サンプルコード】
cat <<'EOF' > test
line1
lne2
line3
EOF


【実行結果】(testファイルの内容)
line1
line2
line3

Rubyのヒアドキュメントの基本的な書き方や特徴

Rubyでもヒアドキュメントを使うことができます。製品となるプログラムの中で使うことはあまりないと考えられますが、開発中にテストやサンプルコードなどで便利に使えるので、ヒアドキュメントの識別子と使い方について、覚えておきましょう。

Rubyでは、ヒアドキュメントの書き方には基本となる3種類の書き方があります。識別子の書き方を変えることで、さらに4種類の異なる使い方ができます。

Rubyのヒアドキュメントの特徴

Rubyでヒアドキュメントを使うのは、複数行にまたがる文字列を出力したいときだと覚えておくと良いでしょう。長文となるSQL文を書くときや、HTML文を書くときなどにも使えます。1行だけのヒアドキュメントも記述できますが、実質あまり意味がありません。

テストコードの中でテストファイルを読むのではなく、ヒアドキュメントでサンプルデータを与えるという使い方もできます。

Rubyのヒアドキュメントの基本的な書き方

Rubyでは、以下の3つのパターンのヒアドキュメントの書き方ができます。

・<<識別子
・<<-識別子
・<<~識別子


Rubyでは、「<<」「<<-」「<<~」を使って、識別子から次の識別子までの間に書かれた文字列をヒアドキュメントとして使います。

<<識別子

「<<識別子」は、Rubyのヒアドキュメントの基本型です。始点の識別子「<<識別子」から、次に出てくる識別子までの囲まれている部分に、ヒアドキュメントとして使いたい文字列を記述します。

【コード記述例】
<<SQL
select count(*) from users where created_at between '1970-01-01' and '2018-10-11'
SQL

<<-識別子

「<<-」と「<<」の異なる点は、終端となる識別子のインデントを設定できるか否かです。「<<」を使った場合は、終端の識別子は行頭に記述しなければなりませんが、「<<-」は字下げが可能です。

【記述例の比較】
・<<EOSの場合
変数 = <<EOS
EOS

・<<-EOSの場合
変数 = <<-EOS
EOS

<<~識別子

プログラムの体裁として、ヒアドキュメントの行頭に空白文字列を入れたものの、実際にデータとして使いたいのは空白を除いた文字列のみ、ということもあります。このような場合、「<<~」を使うと、ヒアドキュメントの行頭の空白を無視してくれます。

【比較例】
puts <<-EOS
English
EOS

puts <<~EOS
Japnese
EOS


【表示例】
English
Japnese

ヒアドキュメントの式展開について

式展開とは、「文字列の中で式や変数を展開する」ことを指します。この説明だけでは、ピンとこない人も多いでしょう。「式展開」の実例をみてみましょう。

【サンプルコード】
string = "a"
p "#{string}, b, c"


【実行結果】
a,b,c

この例ではstringという変数が、b、cという文字列と一緒に出力されますが、実行結果は変数名ではなく、変数が展開され、変数の内容が出力されています。

<<‘識別子’の場合

Rubyでヒアドキュメントの識別子を「'(シングルクォーテーション)」で囲むと、ヒアドキュメント全体を囲ったのと同じ効果となります。つまり書いた文字がそのまま出力されます。式展開はされません。

【コード記述例】
<<'EOS' 
sample\n sample\n sample\n sample\n
EOS


【実行結果】
" sample\\n sample\\n sample\\n sample\\n\n"

<<`識別子`の場合

Rubyでヒアドキュメントの識別子を「`(バッククォート)」で囲むと、ヒアドキュメントの内容は、コマンドとして実行されます。コマンド実行の前に式展開も行われるので、 #{} が使えます。

【コード記述例】
<<`EOS`
echo #{Time.current}
EOS


【実行結果】
"2019-02-12 00:08:53 +0900\n"

<<“識別子”の場合

Rubyでヒアドキュメントの識別子を「"(ダブルクォーテーション)」で囲むと、ヒアドキュメント全体を囲ったのと同じ効果となります。#{} を使って式展開することができます。

【コード記述例】
<<"EOS"
One Day ago : #{1.day.ago}
EOS


【実行結果】
" One Day ago : 2019-03-11 00:32:59 +0900"

その他のヒアドキュメントの使い方

Rubyのヒアドキュメントの書き方は、識別子の書き方を変えることで、以下の4種類の使い方ができます。

・式展開ヒアドキュメント(<<EOS /<<"EOS”)
・非式展開ヒアドキュメント(<<'EOS')
・コマンド出力ヒアドキュメント(<<`EOS`)
・インデントヒアドキュメント(<<-EOS)

Rubyの中でどう使っていくか見てみましょう。

式展開ヒアドキュメント

以下の例では、識別子「EOS」を「"」で囲んだ場合も実行結果は同じになります。ヒアドキュメントの中に変数を記述すると、式展開され、変数にセットされた値が使われます。

【実行コード】
int= 123
str = <<EOS
one
two
three
#{int}
EOS
print str


【実行結果】
one
two
three
123

非式展開ヒアドキュメント

ヒアドキュメントに同じ内容の文字列を記述しても、識別子を「'」で囲むと、非式展開ヒアドキュメントの扱いになります。以下の例では、ヒアドキュメントの中の変数は式展開されず、#{}を含め、単なる文字列として扱われます。

【実行コード】
int= 123
str = <<'EOS'
one
two
three
#{int}
EOS
print str


【実行結果】
one
two
three
#{int}

コマンド出力ヒアドキュメント

ヒアドキュメントとして、コマンド出力リテラルに相当する、コマンド実行結果を使うことができます。この場合は、識別子をバッククォートで囲みます。

【実行コード】
str = <<`EOS`
echo "What time is it now?"
date
EOS
print str


【実行結果】
what time is it now?
Mon Mar 25 23:53:36 JST 2019

インデントヒアドキュメント

インデントヒアドキュメントは、「<<-識別子」の形式で使えます。ここでいうインデントは、識別子の終端のインデントのことで、ヒアドキュメントの内容そのものではありません。

プログラムの記述を見やすくするためには有効ですが、ヒアドキュメント自体がインデント設定できるわけではないので、きちんと覚えておきましょう。

ヒアドキュメントの使い方

ヒアドキュメントを実際にRubyを使ったプログラム開発の中で使う場面としては、以下のような用途が考えられます。

・メソッドの引数に使う
・複数のヒアドキュメントを使う
・ヒアドキュメントの中の空文字を削除する

これらの使い方を覚えておけば、さらに応用して効率的なプログラム開発ができることでしょう。

メソッドの引数に使う

ヒアドキュメントの開始識別子は、Rubyとしては「式」として受け取ります。式として渡すことが可能なメソッドの引数には、ヒアドキュメントの開始識別子を記述することができます。

【サンプルコード】
def method(*aaa)
p aaa
end

method('123', <<EOS, '456')
abc
EOS


【実行結果】
["123", "abc\n", "456"]

複数のヒアドキュメントを使う

ヒアドキュメントの開始識別子は式として扱われます。そのため、複数のヒアドキュメントを1行に記述することもできます。

【サンプルコード】
def method(*aaa)
p aaa
end

method(<<EOS1, <<EOS2, <<EOS3)
one
EOS1
two
EOS2
three
EOS3


【実行結果】
["one\n", "two\n", "three\n"]

ヒアドキュメントの中の空文字を削除する

開始識別子はRubyの中では式として扱われます。開始識別子に文字列を処理するメソッドを使えば、ヒアドキュメント中の空文字を削除することができます。この方法は空文字だけでなく、様々な文字処理に応用できます。

【サンプルコード】
begin
str = <<-EOS.gsub(/^\s+/, '')
 one
two
   three
EOS
end
print str


【実行結果】
one
two
three

Rubyでヒアドキュメントを使ってみよう

Rubyにおけるヒアドキュメントの使い方について、理解できたでしょうか。説明を読むだけでは、イメージがわきにくくても、サンプルコードを実行してみると、使い方も理解しやすいでしょう。

Rubyのヒアドキュメントの使い方を知っていると、データを変えながら試してみたい場合や、コマンドの実行結果を含んだデータを使いたい場合など、効率的にプログラミングを進めることができます。積極的に取り入れてみましょう。

Related