Rubyでプログラムを記述する際、複数行にわたる長い文字列を扱う場面は非常に多く存在します。
通常のダブルクォートやシングルクォートでは、改行を含めようとするとコードの見通しが悪くなりがちです。
こうした課題をスマートに解決するために用意されている機能が、ヒアドキュメントです。
ヒアドキュメントを活用することで、SQLクエリやHTMLのテンプレート、長文のメッセージなどをソースコード内に美しく記述できます。
本記事では、Rubyにおけるヒアドキュメントの基本的な書き方から、インデントの制御、変数展開のルールまでを詳しく解説します。
Rubyのヒアドキュメントとは
ヒアドキュメントとは、特定の識別子を使って複数行の文字列を簡潔に表現するための記法です。
Rubyにおけるヒアドキュメントは、<< という記号の後に任意の識別子を記述することで開始されます。
識別子には TEXT や EOF (End Of File) といった名前が使われることが一般的です。
開始した識別子と同じ文字列が単独で現れるまでの間、すべての行が文字列として扱われます。
この機能を利用することで、エスケープシーケンスを多用することなく、直感的に長いテキストを定義できます。
基本的なヒアドキュメントの書き方
まずは、最も標準的なヒアドキュメントの記述方法を確認しましょう。
以下のコードは、基本的なヒアドキュメントの使用例です。
# 標準的なヒアドキュメントの例
text = <<EOS
Rubyのヒアドキュメントは、
このように複数行の文章を
そのまま変数に代入できます。
EOS
puts text
Rubyのヒアドキュメントは、
このように複数行の文章を
そのまま変数に代入できます。
この記述方法では、終端の識別子である EOS は必ず行の先頭に置く必要があります。
終端識別子の前にスペースなどの空白文字を入れるとエラーになるため注意が必要です。
インデントを許可する「<<-」の活用
標準的な記法では終端識別子を先頭に書かなければなりませんが、これはメソッドやクラスの中で記述する際にインデントが崩れる原因になります。
そこで、<<- (ハイフン付き) という記法を使用します。
この記法を使うと、終端の識別子をインデントさせることが可能になります。
def display_message
# ハイフン付きのヒアドキュメント
message = <<-MSG
このメッセージはインデントされています。
終端のMSGもインデントして記述できます。
MSG
puts message
end
display_message
ただし、この記法では「文字列そのもの」に含まれる先頭の空白は保持されます。
つまり、出力結果にもインデントが含まれることになります。
このメッセージはインデントされています。
終端のMSGもインデントして記述できます。
余分なインデントを除去する「<<~」の利便性
Ruby 2.3から導入された <<~ (チルダ付き) は、非常に便利な記法です。
この記法は「リテラル内で最も浅いインデント」に合わせて、各行の先頭にある空白を自動的に取り除いてくれます。
これにより、ソースコード上の見た目を美しく保ちつつ、出力結果からは不要な空白を消すことができます。
def clean_format
# チルダ付きのヒアドキュメント
text = <<~TEXT
こちらはチルダ付きです。
コード上はインデントされていますが、
出力時には先頭の空白が削除されます。
TEXT
puts text
end
clean_format
こちらはチルダ付きです。
コード上はインデントされていますが、
出力時には先頭の空白が削除されます。
現代のRuby開発においては、この <<~ が最も推奨される記述スタイルです。
ヒアドキュメントにおける変数展開とクォートの使い分け
ヒアドキュメントでは、通常の文字列と同様に #{} を使った変数展開が可能です。
識別子の囲み方によって、変数展開を「許可するか」「禁止するか」を制御できます。
ダブルクォートで囲む場合 (デフォルト)
識別子をダブルクォートで囲むか、何も囲まない場合は変数展開が有効になります。
name = "Rubyist"
# 変数展開を有効にする
html = <<"HTML"
<p>こんにちは、#{name}さん</p>
HTML
puts html
<p>こんにちは、Rubyistさん</p>
シングルクォートで囲む場合
識別子をシングルクォートで囲むと、変数展開やエスケープシーケンスが無効化されます。
これは、スクリプトの内容をそのまま文字列として扱いたい場合に非常に便利です。
name = "Rubyist"
# 変数展開を無効にする
plain_text = <<'TEXT'
#{name}さん、こんにちは。
この部分はそのまま出力されます。
TEXT
puts plain_text
#{name}さん、こんにちは。
この部分はそのまま出力されます。
バックスラッシュで囲む場合
稀なケースですが、識別子をバッククォートで囲むと、ヒアドキュメントの内容がシェルコマンドとして実行されます。
そのコマンドの実行結果が文字列として取得できるという、強力な機能です。
# シェルコマンドとして実行
file_list = <<`COMMAND`
ls -l
COMMAND
puts file_list
ヒアドキュメントの応用的な使い方
ヒアドキュメントは単に変数を代入するだけでなく、式の一部としても利用できます。
メソッドの引数に渡す
ヒアドキュメントを直接メソッドの引数として渡すことが可能です。
# putsメソッドの引数に直接渡す
puts <<~INFO
現在の時刻は #{Time.now} です。
ヒアドキュメントは引数にもなります。
INFO
メソッドをチェーンさせる
ヒアドキュメントで生成された文字列に対して、直接メソッドを呼び出すことができます。
例えば、文字列を全て大文字にしたり、特定の文字を置換したりする場合に便利です。
# ヒアドキュメントに対してchompやupcaseを適用
content = <<~LOWER.upcase.chomp
this is a small text.
LOWER
p content
"THIS IS A SMALL TEXT."
複数のヒアドキュメントを同時に使用する
Rubyでは、1行の中に複数のヒアドキュメントを開始する記述が可能です。
非常にテクニカルな書き方ですが、複数のデータを一度に定義する際に役立ちます。
# 1行で2つのヒアドキュメントを開始
print <<FIRST, <<SECOND
最初の文字列
FIRST
次の文字列
SECOND
ヒアドキュメントの活用シーン
具体的にどのような場面でヒアドキュメントを使うべきか、代表的な例をいくつか紹介します。
SQLクエリの記述
データベースを操作する際、複数行にわたるSQL文を記述するのに最適です。
query = <<~SQL
SELECT users.id, users.name, orders.amount
FROM users
INNER JOIN orders ON users.id = orders.user_id
WHERE users.active = true
ORDER BY orders.created_at DESC
SQL
HTMLテンプレートの作成
プログラム内で動的にHTMLを生成する場合、構造を維持したまま記述できます。
html_layout = <<~HTML
<div class="container">
<h1>Welcome to Our Site</h1>
<p>最新のニュースをお届けします。</p>
</div>
HTML
長文のテストデータ
テストコード (RSpecなど) において、期待される出力結果や入力用ファイルを定義する際にも多用されます。
ヒアドキュメント利用時の注意点
便利なヒアドキュメントですが、いくつか注意すべきポイントがあります。
識別子の命名
識別子には何を使っても動作しますが、内容が推測しやすい名前を付けるのがマナーです。
一般的には、SQL文なら SQL、HTMLなら HTML、汎用的なテキストなら TEXT や EOS が選ばれます。
空白文字の混入
<<~ を使用しない場合、コードのインデントがそのまま文字列のスペースとして保存されます。
意図しない空白が含まれると、ログ出力やファイル書き出しの際にフォーマットが崩れる原因となります。
終端識別子のルール
<<- や <<~ を使わない場合、終端識別子の前後にスペースを置いてはいけません。
識別子が正しく認識されないと、スクリプトの末尾までずっと文字列として扱われ、Syntax Errorを引き起こします。
各記法の比較まとめ
今回解説した3つの記法の違いを以下の表にまとめました。
| 記法 | 終端識別子のインデント | 本文のインデント削除 | 主な用途 |
|---|---|---|---|
<<LABEL | 不可 | なし | 古いコードや、インデントが不要な場面 |
<<-LABEL | 可能 | なし | 終端ラベルのみ整理したい場合 |
<<~LABEL | 可能 | あり (最も浅い部分に揃える) | モダンなRuby開発の推奨スタイル |
まとめ
Rubyのヒアドキュメントは、可読性の高いコードを書くために欠かせない機能です。
特に <<~ を使うことで、コードのインデントを美しく保ったまま、クリーンな文字列データを定義できます。
また、識別子をシングルクォートで囲むかダブルクォートで囲むかにより、変数展開の挙動を制御できる点も重要です。
これらのルールを正しく理解し、SQLやHTML、長文テキストの扱いに活用してください。
適切な記法を選択することで、メンテナンス性の高い素晴らしいRubyコードを書き上げることができるでしょう。
