This was the tip of the week in the September 23, 2021 Ruby Weekly Newsletter.


We sometimes see Ruby snippets like %w(some strings) or %s(some other strings) or %Q(even more #{strings}). It can be a little unclear what is happening. What’s the % syntax? What do the different letters do? When are they uppercase or lowercase?

This is usually referred to as ‘general delimited input’, although I’ve also heard this called ‘percent syntax’. Either way, it’s a shorthand for creating strings, arrays, symbols, or regular expressions. And, as we’ll see below, each different letter creates an object of a different class.

With one exception, lowercase delimiters ignore interpolation, while uppercase delimiters compute interpolated values.

General delimited input is used most frequently for constants which are arrays of Strings, in codebases which prefer the syntax for multi-line strings, and for regexes.

Let’s take a brief tour of a handful of general delimited input syntaxes, and what they do:

%w() or %W() - Arrays of Strings

These split the arguments on space, and create arrays where each element in the array is a String

  • %w() no interpolation, so will split ‘interpolated-looking’ values on spaces too:
    %w(some values #{1 + 1})
    => ["some", "values", "\#{1", "+", "1}"]
    
  • %W() with interpolation:
    %W(some values #{1 + 1})
    => ["some", "values", "2"]
    

%i() or %I() - Arrays of Symbols

Same as above, except instead of strings, each element is a Symbol.

  • %i() no interpolation, so will split interpolated values on spaces too:
    %i(some values #{1 + 1})
    => [:some, :values, :"\#{1", :+, :"1}"]
    
  • %I() with interpolation:
    %I(some values #{1 + 1})
    => [:some, :values, :"2"]
    

%q() or %Q() - Strings

These will turn the argument into a string.

  • %q() no interpolation, so will split interpolated values on spaces too:
    %q(some values #{1 + 1})
    => "some values \#{1 + 1}"
    
  • %Q() with interpolation:
    %Q(some values #{1 + 1})
    => "some values 2"
    

%s() - Symbols

%s() no interpolation, so will split interpolated values on spaces too:

%s(some values #{1 + 1})
=> :"some values \#{1 + 1}"

%r() - Regex

%r() is the only exception to the capitalization / interpolation rule. %r() will give us a regex with interpolation:

%r(some values #{1 + 1})
=> /some values 2/

Hopefully next time you see, or need to use general delimited input, you now know the appropriate delimiter to use.

Note: The characters delimiting the contents (( and ) in the examples above) don’t have to be parentheses, but could be square brackets, braces, angle brackets, and others - but that’s a tip for another day.