986

I'm looking at the documentation for FileUtils.

I'm confused by the following line:

FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6'

What does the %w mean? Can you point me to the documentation?

1

8 Answers 8

1434

%w(foo bar) is a shortcut for ["foo", "bar"]. Meaning it's a notation to write an array of strings separated by spaces instead of commas and without quotes around them. You can find a list of ways of writing literals in zenspider's quickref.

18
  • 223
    Also, the parenthesis can be almost any other character such as square brackets %w[...], curly braces %w{...} or even something like exclamation marks %w!...!. All of these have the same behavior (returning an array).
    – ryanb
    Commented Aug 13, 2009 at 21:40
  • 171
    The easiest way to mnemonically remember what this means is "Whitespace (w) separated array".
    – Julik
    Commented Aug 14, 2009 at 9:36
  • 10
    See "General Delimited Input" here ruby-doc.org/docs/ProgrammingRuby/html/language.html
    – Jared Beck
    Commented May 27, 2012 at 18:42
  • 141
    If string has spaces, just escape them with \. Ex.: %w(ab\ c def) # => ["ab c", "def"]
    – Dmytro
    Commented Jan 25, 2013 at 19:49
  • 11
    Guess this page would have solved the question, too: ruby-doc.org/core-2.0/doc/syntax/… Commented Jul 21, 2013 at 12:57
591

I think of %w() as a "word array" - the elements are delimited by spaces and it returns an array of strings.

Here are all % literals:

  • %w() array of strings
  • %r() regular expression.
  • %q() string
  • %x() a shell command (returning the output string)
  • %i() array of symbols (Ruby >= 2.0.0)
  • %s() symbol
  • %() (without letter) shortcut for %Q()

The delimiters ( and ) can be replaced with a lot of variations, like [ and ], |, !, etc.

When using a capital letter %W() you can use string interpolation #{variable}, similar to the " and ' string delimiters. This rule works for all the other % literals as well.

abc = 'a b c'
%w[1 2#{abc} d] #=> ["1", "2\#{abc}", "d"]
%W[1 2#{abc} d] #=> ["1", "2a b c", "d"]
3
  • 37
    As of Ruby 2.0.0 you can also use %i() to generate an array of symbols. Commented Sep 20, 2013 at 8:59
  • 13
    There's also %() (or %[] or %{}) which gives a double quoted string and escapes double quotes, like %Q(). E.g. %("sender name" <[email protected]>) # => "\"sender name\" <[email protected]>"
    – Dennis
    Commented Jan 14, 2015 at 14:30
  • 2
    @ChristopherOezbek How about %i[nterned]? Since symbols are interned strings. Commented Jul 6, 2021 at 19:01
61

There is also %s that allows you to create any symbols, for example:

%s|some words|          #Same as :'some words'
%s[other words]         #Same as :'other words'
%s_last example_        #Same as :'last example'

Since Ruby 2.0.0 you also have:

%i( a b c )   # => [ :a, :b, :c ]
%i[ a b c ]   # => [ :a, :b, :c ]
%i_ a b c _   # => [ :a, :b, :c ]
# etc...
34

%W and %w allow you to create an Array of strings without using quotes and commas.

1
28

Though it's an old post, the question keep coming up and the answers don't always seem clear to me, so, here's my thoughts:

%w and %W are examples of General Delimited Input types, that relate to Arrays. There are other types that include %q, %Q, %r, %x and %i.

The difference between the upper and lower case version is that it gives us access to the features of single and double quotes. With single quotes and (lowercase) %w, we have no code interpolation (#{someCode}) and a limited range of escape characters that work (\\, \n). With double quotes and (uppercase) %W we do have access to these features.

The delimiter used can be any character, not just the open parenthesis. Play with the examples above to see that in effect.

For a full write up with examples of %w and the full list, escape characters and delimiters, have a look at "Ruby - %w vs %W – secrets revealed!"

25

Instead of %w() we should use %w[]

According to Ruby style guide:

Prefer %w to the literal array syntax when you need an array of words (non-empty strings without spaces and special characters in them). Apply this rule only to arrays with two or more elements.

# bad
STATES = ['draft', 'open', 'closed']

# good
STATES = %w[draft open closed]

Use the braces that are the most appropriate for the various kinds of percent literals.

[] for array literals(%w, %i, %W, %I) as it is aligned with the standard array literals.

# bad
%w(one two three)
%i(one two three)

# good
%w[one two three]
%i[one two three]

For more read here.

1
  • 2
    If you're seeing an error from Rubocop, this is the notation it's looking for.
    – Jason L.
    Commented Jan 28, 2022 at 18:04
13

Excerpted from the documentation for Percent Strings at http://ruby-doc.org/core/doc/syntax/literals_rdoc.html#label-Percent+Strings:

Besides %(...) which creates a String, the % may create other types of object. As with strings, an uppercase letter allows interpolation and escaped characters while a lowercase letter disables them.

These are the types of percent strings in ruby:
...
%w: Array of Strings

2
  • 2
    Geez thanks! I was beginning to think it didn't exist. The rubydoc links provided by others are broken.
    – Gerry
    Commented Apr 12, 2015 at 8:59
  • The documentation wasn't for these wasn't included in the RubyDocs for quite a while. Commented Mar 22, 2016 at 17:26
1

I was given a bunch of columns from a CSV spreadsheet of full names of users and I needed to keep the formatting, with spaces. The easiest way I found to get them in while using ruby was to do:

names = %(Porter Smith
Jimmy Jones
Ronald Jackson).split("\n")

This highlights that %() creates a string like "Porter Smith\nJimmyJones\nRonald Jackson" and to get the array you split the string on the "\n" ["Porter Smith", "Jimmy Jones", "Ronald Jackson"]

So to answer the OP's original question too, they could have wrote %(cgi\ spaeinfilename.rb;complex.rb;date.rb).split(';') if there happened to be space when you want the space to exist in the final array output.

Not the answer you're looking for? Browse other questions tagged or ask your own question.