TIL on
Ruby’s % notation is more powerful than you think
I already knew the basics—%w for word arrays, %i for symbol arrays, %q/%Q for strings, %r for regexps—but there’s more to the % notation than I realized.
%() defaults to interpolated strings
%Q is the interpolated string literal, but you can drop the Q entirely. %() is equivalent to %Q(), which is equivalent to double-quoted strings:
path = "/some/path"
%(filename="#{path}")
# => "filename=\"/some/path\""
This is great when your string contains quotes and you don’t want to escape them.
Capital letters = interpolation
The lowercase/uppercase pattern is consistent: lowercase is non-interpolated, uppercase is interpolated.
language = "Ruby"
# Non-interpolated (lowercase)
%w[hello #{language}] # => ["hello", "\#{language}"]
%i[hello #{language}] # => [:hello, :"\#{language}"]
# Interpolated (uppercase)
%W[hello #{language}] # => ["hello", "Ruby"]
%I[hello #{language}] # => [:hello, :Ruby]
%x for shell commands
%x works like backticks but with the % delimiter flexibility:
%x(echo "hello from the shell")
# => "hello from the shell\n"
%s for non-interpolated symbols
%s(hello world) # => :"hello world"
%s(#{nope}) # => :"\#{nope}"
Any non-alphanumeric character works as a delimiter
I’d only ever used (), [], {}, ||, and <>, but you can use any single non-alphanumeric character—even whitespace:
%w#foo bar# # => ["foo", "bar"] (array of words with hashes as delimiters)
%i!foo bar! # => [:foo, :bar] (array of symbols with exclamation marks as delimiters)
%r.foo bar. # => /foo bar/ (regex with periods as delimiters)
% test # => "test" (string with spaces as delimiters)
% foo\ bar # => "foo bar" (string with spaces as delimiters, with an escaped space inside—please don't)
Paired delimiters allow unescaped nesting
If you use (), [], {}, or <>, you can include those same characters unescaped inside the literal—as long as they appear in balanced pairs:
%(string (syntax) is pretty flexible)
# => "string (syntax) is pretty flexible"
%w[one [two three] four]
# => ["one", "[two", "three]", "four"]