Ruby のパーセントリテラルの書き方


Ruby のコードで, 一見するとなんだろうと思う不思議な見た目のパーセントリテラル, その書き方を紹介します.

リテラルとは

そもそもリテラルとはどのような意味なのでしょう?

Wikipedia によると次のように定義されています:

In computer science, a literal is a notation for representing a fixed value in source code.

コンピュータサイエンスでは, リテラルとはソースコード中の固定された値を表現するための表記法.

つまりはリテラルって foo, bar のような変数ではなくて, String の "Hello World" とか, Integer の 1, 2, 3 とかそういう決められた値そのものを定義するための表記法です.

パーセントリテラルとは, そのようなリテラルを表記するときに % を頭につけるので, そのように呼ばれているのです.

なので他のリテラルと何も変わらないのです.

パーセントリテラルの書き方

まずパーセントリテラルの大まかな書き方の説明をさせていただいてから, それぞれの具体的な書き方を紹介させていただきます.

大まかな書き方

パーセントリテラルを書く場合, まず % を書きそのまま括弧を付け足して %() とし String のパーセントリテラルとするか, もしくは i, q, r, s, w, x のいずれかの文字を付け足した後に () を付け足すかします. また最後に付け足す () という文字は () である必要はなく [], {}, <> といったものに加えて %, |, ^ などの文字も使えます.

また % の後につけられる i, q, w の文字は, 大文字の I, Q, W でも書くことができますが, その場合意味が変わってきます.

i, q, w は String Interpolation やエスケープシーケンスを使用することができないですが, I, Q, W はそれらを使用することができます.

ちょうど String の ''"" の違いとほぼ一緒になりますね.

ほぼと言うのは '' の方は \' というエスケープシーケンスだけ使うことができます .

%, %i, %q, %r, %s, %w, %x のそれぞれの意味は次のようになります:

  • % – String
  • %i – Symbol の Array
  • %q – String
  • %r – Regexp
  • %s – Symbol
  • %w – String の Array
  • %x`` と同じ

また %, %i, %q, %r, %s, %w, %x の後につけられる (), [], {} といったものは Ruby Style Guide によりますと, 次のように選択されるといいとのことです:

  • %()
  • %i[]
  • %q()
  • %r{}
  • %s()
  • %w[]
  • %x()

具体的な書き方

それぞれのパーセントリテラルの具体的な書き方は次のようになります.

% の場合

String を作ります.

"" でも同じようなことができますが, ダブルクオートをエスケープする必要がないので, Interpolation に加えて " も書きたいという場合に使われます:

puts %("1 + 1" is #{ 1 + 1}.)  # "1 + 1" is 2.

なので Interpolation を使うけど " は使わないよという場合は, "" による String にします:

puts "Today is #{ Time.now.strftime('%B %d, %H') }"  # Today is June 25, 14

Interpolation や " を使う場合であっても複数行になる場合は Heredoc を使います:

puts <<EOF
"#{ (1..10).to_a.join(' + ') }"
becomes #{ (1..10).inject(&:+) }.
EOF

# "1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10"
# becomes 55.

もしくはシングルクオートとダブルクオートの両方を一緒に書きたいという時に使われます:

puts %("I'm going there.", she said.)  # "I'm going there.", she said.

%i / %I の場合

Symbol の Array を作ります.

一つ一つの要素はスペースで区切ります:

%i[Hello World]  # => [:Hello, :World]

スペースをそのまま入力する場合, \ でエスケープする必要があります:

%i[Ruby Ruby\ on\ Rails]  # => [:Ruby, :"Ruby on Rails"]

Interpolation を使わない場合は %i を使い:

%i[a b c]  # => [:a, :b, :c]

Interpolation を使う場合は %I を使います:

%I[1024 #{ 1024**2 } #{ 1024**3 }]  # => [:"1024", :"1048576", :"1073741824"]

%q / %Q の場合

String を作ります.

% 同様, シングルクオートもダブルクオートもエスケープする必要がありません.

なので '" の両方を書くという場合は %q を使い:

puts %q("I'm going there.", she said.)  # "I'm going there.", she said.

Interpolation に加えて " も書きたいという場合は %Q を使います:

%Q("1 + 1" is #{ 1 + 1}.)  # "1 + 1" is 2.

なので %Q% と全く同じものなので, %%Q の速記のエイリアスになります.

%r の場合

// と同じ, 正規表現オブジェクト Regexp を作ります.

正規表現パターンで / にマッチさせたい時に使います.

例えば URL にマッチする正規表現パターンを作る時に便利です:

%r{/blog/\d\d\d\d/\d\d/\d\d/}                  # => /\/blog\/\d\d\d\d\/\d\d\/\d\d\//
%r{/blog/#{ Time.now.strftime('%Y/%m/%d') }/}  # => /\/blog\/2018\/06\/25\//

%s の場合

Symbol を作ります.

スペースが含まれた Symbol も, そのままスペースを入力して作ることができます:

%s(Hello World)  # => :"Hello World"

ただ同じく Ruby Style Guide によるとスペースを含んだシンボルを作る場合, %s() ではなく :"" を使ったほうがより好ましいとコミュニティが決められたように見えるとのことなので, そういうことなのでしょう.

%w / %W の場合

String の Array を作ります.

%i と同じく一つ一つの要素はスペースで区切り, スペースをそのまま書きたい場合は \ でエスケープします.

Interpolation を使わない場合は %w を使い:

%w[Hello World]           # => ["Hello", "World"]
%w[Ruby Ruby\ on\ Rails]  # => ["Ruby", "Ruby on Rails"]

Interpolation を使う場合は %W を使います:

%W[1024 #{ 1024**2 } #{ 1024**3 }]  # => ["1024", "1048576", "1073741824"]

%x の場合

`` と同じ意味になります.

つまりはサブシェルの結果が返ります.

ただその中で echo `date` などさらに `` を使いたいという場合に使われます:

%x(echo `date`)            # => "Mon Jun 25 12:40:18 JST 2018\n"
%x(echo "I am `whoami`.")  # => "I am yu8mada.\n"

まとめ

Ruby のパーセントリテラルは本来 \ でエスケープが必要な文字や, Array の Symbol 要素として : をつけたり, String 要素として '" で囲んだりする必要を省いてくれます.

つまりはより簡潔に書くことができ, 可読性も高くなります.

何より純粋にこんな書き方もできるって楽しいです.

Ruby のパーセントリテラル Rubyist ならぜひ使いこなしたいですね.