What does %w(array) mean?

RubyArraysStringNotation

Ruby Problem Overview


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?

Ruby Solutions


Solution 1 - Ruby

%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.

Solution 2 - Ruby

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"]

Solution 3 - Ruby

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...

Solution 4 - Ruby

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

Solution 5 - Ruby

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!"

Solution 6 - Ruby

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.

Solution 7 - Ruby

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

Solution 8 - Ruby

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDane O'ConnorView Question on Stackoverflow
Solution 1 - Rubysepp2kView Answer on Stackoverflow
Solution 2 - RubyMike WoodhouseView Answer on Stackoverflow
Solution 3 - RubyEradenView Answer on Stackoverflow
Solution 4 - RubyEvan MeagherView Answer on Stackoverflow
Solution 5 - RubyMark CView Answer on Stackoverflow
Solution 6 - RubyRajkaran MishraView Answer on Stackoverflow
Solution 7 - RubyitsnikolayView Answer on Stackoverflow
Solution 8 - RubypjammerView Answer on Stackoverflow