ヒアドキュメントでSQLを読み易くする

Sinatraを使ったメモアプリを開発中です。 rubyファイル内の長くて読みにくいSQLを読み易く記述する方法を調べました。

結論

ヒアドキュメントを使うと長いSQLの可読性が上がるかもしれません。 rubyファイル内のSQLは次のように書き換えることができます。

# SQLを実行するメソッド
def excute(query)
  connection = PG::Connect.new(dbname: memo_app)
  connection.exec(query)
end

# メソッド呼び出し
excute(INSERT INTO memos (id, title, content) VALUES ('#{params[:id]}', '#{params[:title]}', '#{params[:content]}'))

上のメソッド呼び出し部のSQLをヒアドキュメントで書き換えると次のようになります。

excute(<<~SQL)
  INSERT INTO memos (id, title, content)
  VALUES ('#{params[:id]}', '#{params[:title]}', '#{params[:content]}')
SQL

SQLにインデントが追加され、改行が加わることで読み易くなったと個人的には感じます。 上のヒアドキュメントを使った書き方はちょっと特殊なのでポイント毎に解説します。

ヒアドキュメントとは?

ヒアドキュメントは<<識別子 を含む行の次の行から識別子 だけの行の直前までを文字列とする行指向のリテラルです。

print <<EOS      # 識別子 EOS までがリテラルになる
  the string
  next line
EOS

これは以下と同じです。

print "  the string\n  next line\n"

参照: リテラル (Ruby 3.1 リファレンスマニュアル)

ポイント1: ヒアドキュメントの文字列部をインデントする

開始ラベルをチルダを使って<<~識別子 とすることで文字列部をインデントすることができます。

  • インデントの深さは最もインデントが少ない行が基準になる。
  • 出力時には文字列部先頭の空白は除去される。

チルダの有無での出力結果を比較すると以下のようになります。

# チルダ無し
print <<EOS
  the string
    next line
EOS

# 出力結果
  the string
    next line
# チルダ有り
print <<~EOS
  the string
    next line
EOS

# 出力結果
the string
  next line

最もインデントが少ない行が基準になり、先頭の空白のが取り除かれています。

ポイント2: ヒアドキュメントをメソッドの引数に使う

メソッドの引数としてヒアドキュメントを使うことができます。 識別子(<<~EOS)が入った引数の丸括弧を先に閉じる点がかなり特殊だと思います。

def puts_text(s)
  puts s
end

# メソッドの引数をヒアドキュメントで指定
puts_text(<<~EOS)
  This is
    TEXT!
EOS

# 出力結果
This is
  TEXT!

丸括弧を先に閉じない場合でも書けるようですがrubocopでは先に閉じるパターンを推奨しています。

まとめ

ヒアドキュメントは使う機会が少なく殆ど覚えていなかったので良い復習になったので良かった。 少しでも読み易くて綺麗なコードが書けるようになりたい。

参照

Rubyのヒアドキュメントの書き方いろいろ - Hack Your Design!

Rubyのヒアドキュメント 4パターンのまとめ -- ぺけみさお

rubocop/ruby-style-guide: A community-driven Ruby coding style guide