Now the %i[…] Question
Question:
Why is
iused for symbols andwfor strings?
This comes from Ruby’s percent literal syntax.
Ruby provides a family of % literals.
For example:
%w[one two three]
means:
["one", "two", "three"]
while:
%i[one two three]
means:
[:one, :two, :three]
The letters are essentially mnemonics for the type being produced.
Why w?
%w can be thought of as:
word array
%w[apple banana orange]
produces:
["apple", "banana", "orange"]
These are strings.
The w is commonly understood as referring to words.
For example:
%w[admin editor viewer]
is a convenient way to write:
["admin", "editor", "viewer"]
Why i?
%i means:
symbol array
%i[admin editor viewer]
produces:
[:admin, :editor, :viewer]
The i is associated with identifiers/symbols in Ruby’s percent-literal syntax.
So you can remember:
%i → symbols%w → strings
Don’t think of the i as meaning “integer” here.
It does not mean integer.
Compare Them Directly
%i[admin editor viewer]
returns:
[:admin, :editor, :viewer]
while:
%w[admin editor viewer]
returns:
["admin", "editor", "viewer"]
You can verify:
%i[admin editor].first.class# => Symbol
and:
%w[admin editor].first.class# => String
Why Would I Use %i Instead of [:admin, :editor, :viewer]?
Mostly readability and convenience.
Compare:
ROLES = [ :admin, :manager, :editor, :viewer]
with:
ROLES = %i[ admin manager editor viewer]
The second makes it visually obvious:
“This is a list of symbols.”
It is particularly nice for Rails configuration:
SUPPORTED_FORMATS = %i[ json xml csv]
or:
PERMISSIONS = %i[ read write delete publish]
%i Supports Interpolation Differently
There’s an important distinction:
%i[hello #{name}]
does not interpolate name.
For interpolation, Ruby provides uppercase I:
%I[hello #{name}]
For example:
name = "ruby"%I[hello #{name}]
produces:
[:hello, :ruby]
Similarly, lowercase/uppercase pairs exist elsewhere:
%w[hello #{name}]
does not interpolate.
%W[hello #{name}]
does interpolate.
So:
%i → symbols, no interpolation%I → symbols, interpolation%w → strings, no interpolation%W → strings, interpolation
This is a useful distinction to know for interviews.
Ruby’s % Literal Family
Once you understand %i and %w, the rest becomes easier.
Ruby has several percent literals:
%q[hello]
Single-quoted-style string.
%Q[hello #{name}]
Double-quoted-style string with interpolation.
%w[one two three]
Array of strings.
%W[one #{two}]
Array of interpolated strings.
%i[one two three]
Array of symbols.
%I[one #{two}]
Array of interpolated symbols.
%r{/users/\d+}
Regular expression.
%s[foo]
Symbol literal.
%x[ls -la]
Executes a shell command and returns its output.
The Mental Model I’d Recommend
Don’t memorize %i as some arbitrary Ruby trick.
Think:
% + type + delimiter
For example:
%i[admin editor]
means:
%+i = symbol array+[...] = delimiter
Likewise:
%w[admin editor]
means:
%+w = word/string array+[...] = delimiter
And the delimiter isn’t necessarily [].
You can use:
%i[admin editor]%i(admin editor)%i{admin editor}%i<admin editor>
Although [] is by far the most common/readable form
Percent literals:
%i # symbols%w # words/strings%I # interpolated symbols%W # interpolated strings