58
%w[ ]   Non-interpolated Array of words, separated by whitespace
%W[ ]   Interpolated Array of words, separated by whitespace

Usage:

p %w{one one two three 0 1 1 2 3} # = > ["one", "one", "two", "three", "0", "1", "1", "2", "3"]
p %W{one one two three 0 1 1 2 3} # = > ["one", "one", "two", "three", "0", "1", "1", "2", "3"]
p %w{C:\ C:\Windows} # => ["C: C:\\Windows"]
p %W{C:\ C:\Windows} # => ["C: C:Windows"]

My question is... what's the difference?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
RyanScottLewis
  • 13,396
  • 16
  • 56
  • 84

3 Answers3

84

%W treats the strings as double quoted whereas %w treats them as single quoted (and therefore won’t interpolate expressions or numerous escape sequences). Try your arrays again with ruby expressions and you'll see a difference.

EXAMPLE:

myvar = 'one'
p %w{#{myvar} two three 1 2 3} # => ["\#{myvar}", "two", "three", "1", "2", "3"]
p %W{#{myvar} two three 1 2 3} # => ["one", "two", "three", "1", "2", "3"]
acconrad
  • 3,201
  • 1
  • 22
  • 31
  • 1
    Check the edit, I like your example, it explains alot. The output of the last two lines in my example confuses me. – RyanScottLewis Apr 22 '11 at 03:01
  • Again, you're not using a ruby expression, it's not surrounded by "#{}". The backslash is a special character in Ruby that is used to interpret other special characters literally, and you're using that in the context of a string, not an expression. That explains why the backslashes are getting bounced in the double quote and not the single quote. – acconrad Apr 22 '11 at 03:04
  • 1
    I think c00lryguy's point is deeper. 1) Even though `'\ '` = `"\\ "`, the backslash is gone with `%w{}`. 2) There is also a general question of when a backslash is ignored as in `"\W"` = `"W"` as seen with `%W{}`. – sawa Apr 22 '11 at 03:16
  • 1
    Slashes are never ignored in double-quoted strings, they are always interpreted as an escape. sometimes that escape may be unneeded, such as in "\W", but the slash will always be consumed. In single quoted strings, they are only consumed when the character actually needed to be escaped. – marcus erronius Dec 12 '12 at 20:37
6

Let's skip the array confusion and talk about interpolation versus none:

irb(main):001:0> [ 'foo\nbar', "foo\nbar" ]
=> ["foo\\nbar", "foo\nbar"]
irb(main):002:0> [ 'foo\wbar', "foo\wbar" ]
=> ["foo\\wbar", "foowbar"]

The difference in behavior is consistent with how single-quoted versus double-quoted strings behave.

Phrogz
  • 296,393
  • 112
  • 651
  • 745
1

To demonstrate a case with interpolation and sequence escape for both literals, we assume that:

>> a = 'a'
=> "a"

The lower-case %w percent literal:

>> %w[a#{a} b#{'b'} c\ d \s \']
=> ["a\#{a}", "b\#{'b'}", "c d", "\\s", "\\'"]
  • treats all supplied words in the brackets as single-quoted Strings
  • does not interpolate Strings
  • does not escape sequences
  • escapes only whitespaces by \

The upper-case %W percent literal:

>> %W[a#{a} b#{'b'} c\ d \s \']
=> ["aa", "bb", "c d", " ", "'"]
  • treats all supplied words in the brackets as double-quoted Strings
  • allows String interpolation
  • escapes sequences
  • escapes also whitespaces by \

Source: What is the difference between %w and %W array literals in Ruby

aloucas
  • 2,967
  • 1
  • 19
  • 15