Rubyには、いわゆるフォーマット指定と呼ばれるやつに従って文字列を整形するメソッドがいくつかあります。
※ これらの書き方をするとRuboCopに怒られてしまったので、経緯をまとめました。
# どれも "hoge = 1 + 2" と評価される
sprintf('hoge = %s + %s', 1, 2)
format('hoge = %s + %s', 1, 2)
'hoge = %s + %s' % [1, 2]
format
とsprintf
はどちらもKernelのメソッドで、名前が違うだけのエイリアスです。
https://docs.ruby-lang.org/ja/latest/method/Kernel/m/format.html
三番目のString#%
は少し毛色が違いますが、self側をフォーマット指定の文字列とみなしてformat
を呼んでいるだけで、実質的には同じことができるようです。
https://docs.ruby-lang.org/ja/latest/method/String/i/=25.html
推奨される書き方(スタイル)は?
この記事の記述時点では、RuboCopのデフォルト動作は「formatメソッドのみを認める」です。矯正させられます。
hoge.rb:3:18: C: Style/FormatString: Favor format over String#%.
'hoge = %s + %s' % [1, 2]
^
さらに、伝統的な%s
のようなスタイルは推奨されないという怒られ方をします。
hoge.rb:1:16: C: Style/FormatStringToken: Prefer annotated tokens (like %<foo>s) over unannotated tokens (like %s).
format('hoge = %s + %s', 1, 2)
^^
結局どう書けばいいのか
フォーマットの指定にアノテーション <name> を付け、はめ込みたい値はHashで渡すスタイルが推奨されるようです。
format('hoge = %<x>d + %<y>d', x: 1, y: 2)
ちなみに似た記法で %{name} もありますが、推奨されないようです。指定子は明記しろってことですね。
hoge.rb:4:16: C: Style/FormatStringToken: Prefer annotated tokens (like %<foo>s) over template tokens (like %{foo}).
format('hoge = %{x} + %{y}', x: 1, y: 2)
^^^^
なぜそのスタイルが推奨されるのか
RuboCopはスタイルをどれかに統一することを意図しているようで、デフォルトがformat
です。
https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Style/FormatString
元になっているissueは↓のようですが、難解な議論の末に決まったというよりは「あるといいんじゃない?」「いいね!」みたいなラフな経緯に見えます。デフォルトは決めの問題という以上の話ではないのかもしれません?
Cop idea: Enforce preferred style for format string sequences #3438
https://github.com/rubocop-hq/rubocop/issues/3438
%<name> は %{name} よりも良い、という主張については、The Ruby Style Guideを根拠にしているように見えます。
When using named format string tokens, favor %s over %{name} because it encodes information about the type of the value.
https://rubystyle.guide/#named-format-tokens
まとめ
Rubyでは、いわゆるprintf的な文字列整形メソッドが、いくつかのスタイルで提供されています。
現代的な、特にチーム開発でRubyを使用する場合には、RuboCopを導入することも多いと思います。その際に指定されるスタイルはどんなもので、どういった根拠に従っているかを、簡単にですがまとめました。