Rubyの式展開(string interpolation)についてまとめ: `#{}`、`%`、Railsの`?`

1. 一般的な「string interpolation」とは まずは一般的な話から。プログラミング言語で文字列を出力するときに、文字列の一部を変数の値や式の評価結果に差し替えたいことが非常によくあります。 “信号: 赤” “信号: 黄” “信号: 青” 上の文字列リテラル(” “で囲まれている部分)のうち、「赤」「黄」「青」を何らかの方法で変数から送り込んで差し替える操作を一般にstring interpolationと呼びます。 “信号: ●” # ←この●を「赤」「黄」「青」に差し替えたい 3つの文字列リテラルを使い分けるより、●を「赤」「黄」「青」だけ差し替える方が楽ですし、文字列リテラルが無駄に長くならずに済みます。 なお、次のような文字結合によるベタなやり方は、結果は同じでもstring interpolationとは呼ばれないようです。 ● = “赤” # 「赤」「黄」「青」のいずれかが入る “信号: ” + ● #=> “信号: 赤” など 上はいずれも説明用の擬似言語であり、特定の言語ではありません。 他の言語でのstring interpolation string interpolationは言語によってさまざまな構文があり、1つの言語に複数の構文があることもあります。置き換えの場所は「プレースホルダ(placeholder)」とも呼ばれます。 string interpolationは他の言語では多くの場合「文字列補間」という訳語が使われていますが、Rubyでは「式展開」と訳されるのが普通です。 参考: 文字列補間 - Wikipedia 他の言語では、以下もstring interpolationとだいたい同じ意味で使われます。 変数置換: variable interpolation 変数補間: variable substitution 変数置換: variable expansion 本記事では以後「式展開」で統一します。 Rubyの式展開とは 参考: 式展開 — リテラル (Ruby 2.6.0) Rubyで文字列の式展開というと以下のような形で説明されることがよくあります。二重引用符” “の中に#{ }と変数を記述すると変数の値が展開されます。なお、式展開が効くのは二重引用符の中だけであり、一重引用符’ ‘の中では式展開は無効です。 year = “2019” puts “Year: #{year}” #=> Year: 2019 #{ }の中にはRubyのどんな式でもそのまま書けます(引用符も書けます)。以下のようにリテラルも書こうと思えば書けますが、この形ではリテラルにする意味はないと思います。 puts “Year: #{‘The last year of Heisei’}” #=> Year: The last year of Heisei Rubyの#{ }では「#to_sが自動的に効く」という重要な特性があります。このおかげで、#{ }の中にどんな式を置いても文字列に変換されます。詳しくは以下をご覧ください。 Rubyでの文字列連結に「#+」ではなく式展開「#{}」を使うべき理由 式展開のバリエーション(1) あまり使わないと思いますが、式展開#{}の中に#でコメントを書くこともできます。ただしその#から行末の改行までがすべてコメントとみなされるため、式展開の閉じ}”は次の行に書く必要があります。 puts “Year: #{year # 平成最後の年 }” #=> Year: 2019 式展開のバリエーション(2) これもあまり使わないと思いますが、式展開に入れる変数が$で始まる変数(グローバル変数)や@で始まる変数(インスタンス変数やクラス変数)の場合、#{}の{}を省略できます。 @year=2019 puts “Year: #@year” #=> Year: 2019 式展開のバリエーション(3) 式展開#{}の前にバックスラッシュ\を置くと、式展開を抑制できます。 puts “Enter the \#{year}” #=> Enter the #{year} 式展開のバリエーション(4)– %を使う場合 %記号を用いて、式展開と書式設定を一度に行うこともできます。書式設定のためのものなので、式展開と呼んでよいかどうかというのはありますが、利便性のためここに書きました。 puts “Year: %{year}” % { year: 2019 } #=> Year: 2019 %記号について詳しくは以下の記事をご覧ください。 Ruby: パーセント記号 `%` の使い方まとめ 参考: Rubyスタイルガイドでの引用符の使い分け 上述のとおり、Rubyでは二重引用符” “の中で式展開が効き、一重引用符’ ‘の中では効きません。 RubocopのRubyスタイルガイド↓では、二重引用符と一重引用符をスタイル上使い分ける際にこの点も意識するとよいでしょう。 Rubyスタイルガイドを読む: 数値、文字列、日時(日付・時刻・時間) 参考: Pythonの式展開 Pythonでは、引用符の中に{}を記述し、format()を用いて変数を指定することで式展開を行います。 # dateやtimeに値が入っているとする print(“Date: {}”.format(date)) a = “Time: {}”.format(time) print(a) ただし、正規表現でたまたま量指定子などの波かっこ{}が使われていると、そこにformat()が干渉してしまうので、文字列を分割するなどして避けてあげる必要があります。 re = “[^a-zA-Z]{2,3}[{}]$”.format(word) # 末尾の[{}]ではなく{2,3}のところにwordが送り込まれてしまう re = “[^a-zA-Z]{2,3}” + “[{}]$”.format(word) # たとえばこのように分割して回避する なお、{{}}とすることで波かっこをエスケープできるそうです。format()の対象外にはできなさそうですが。 参考: … Continue reading Rubyの式展開(string interpolation)についてまとめ: `#{}`、`%`、Railsの`?`