4

The following two statements will generate the same result:

arr = %w(abc def ghi jkl)

and

arr = ["abc", "def", "ghi", "jkl"]

In which cases should %w be used?

In the case above, I want an array ["abc", "def", "ghi", "jkl"]. Which is the ideal way: the former (with %w) or the later?

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Alpha
  • 13,320
  • 27
  • 96
  • 163
  • With `%w`, you don't need to escape your double-quotes and your code looks cooler. Two good reasons to use `%w`. – oldergod May 10 '13 at 07:18
  • 3
    @oldergod having embedded quotes but no embedded spaces is pretty rare –  May 10 '13 at 07:22

4 Answers4

5

When to use %w[...] vs. a regular array? I'm sure you can think up reasons simply by looking at the two, and then typing them in, and thinking about what you just did.

Use %w[...] when you have a list of single words you want to turn into an array. I use it when I have parameters I want to loop over, or commands I know I'll want to add to in the future, because %w[...] makes it easy to add new elements to the array. There's less visual noise in the definition of the array.

Use a regular array of strings when you have elements that have embedded white-space that would trick %w. Use it for arrays that have to contain elements that are not strings. Enclosing the elements inside " and ' with intervening commas causes visual-noise, but it also makes it possible to create arrays with any object type.

So, you pick when to use one or the other when it makes the most sense to you. It's called "programmer's choice".

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
  • You can escape white-space: `%w(one\ word another\ word)` – Stefan May 10 '13 at 07:34
  • 3
    @Stefan, yes, you can, but that defeats the purpose of using `%w` and adds the visual-noise issue that could better be fixed using quoted strings in a normal array. – the Tin Man May 10 '13 at 07:38
  • +1 for "visual noise". Describes the phenomenon pretty accurately. – 0xCAFEBABE May 10 '13 at 07:39
  • 1
    @theTinMan it depends. IMO `%w[int short long long\ long]` has less visual noise than `["int", "short", "long", "long long"]`. – Stefan May 10 '13 at 07:55
  • That's a middle-ground situation compared to your previous example. At that point it is programmers choice once again. Personally, I would take advantage of how it's laid-out in the source-code to improve readability that is obscured when putting it all on a single line. – the Tin Man May 10 '13 at 15:39
  • Don't forget the most important use case for `%w` which is to confuse newbies, all the while making you look smarter :) Why use something that is easily understandable when you can choose a syntax that will make people reach for StackOverflow? – devius May 28 '14 at 14:00
  • Why use a syntax that is used in more than one language as a commonly-known array definition? Why do things that are common-use by experienced programmers? Why avoid using idioms that force newbies to scramble for the documentation they should have been reading all along? If people don't want to learn new things then they shouldn't try to be programmers. – the Tin Man May 28 '14 at 16:03
0

As you correctly noted, they generate the same result. So, when deciding, choose one that produces simpler code. In this case, it's the %w operator. In the case of your previous question, it's the array literal.

Community
  • 1
  • 1
Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
0

Using %w allows you to avoid using quotes around strings.

Moreover, there are more shortcuts like these:

%W - double quotes
%r - regular expression  
%q - single-quoted string
%Q - double-quoted string
%x - shell command

More information is available in "What does %w(array) mean?"

Community
  • 1
  • 1
Sergii Shevchyk
  • 38,716
  • 12
  • 50
  • 61
0

This is the way I remember it:

%Q/%q is for strings

%Q is for double-quoted strings (useful for when you have multiple quote characters in a string).

Instead of doing this:

“I said \“Hello World\””

You can do:

%Q{I said “Hello World”}

%q is for single-quoted strings (remember single quoted strings do not support string interpolation or escape sequences e.g. \n. And when I say does not "support", I mean that single quoted strings will need process the escape sequence as a special character, in other words, the escape sequence will just be part of the string literal)

Instead of doing this:

‘I said \’Hello World\’’

You can do:

%q{I said 'Hello World'}

But note that if you have an escape sequence in string, that will not be processed and instead treated as a literal backslash and n character:

result = %q{I said Hello World\n}
 => "I said Hello World\\n" 
puts result
I said Hello World\n

Notice the literal \n was not treated as a line break, but it is with %Q:

result =  %Q{I said Hello World\n}
 => "I said Hello World\n" 
puts result
I said Hello World

%W/%w is for array elements

%W is used for double-quoted array elements. This means that it will support string interpolation and escape sequences:

Instead of doing this:

orange = "orange"
result = ["apple", "#{orange}", "grapes"]
 => ["apple", "orange", "grapes”]

you can do this:

result = %W(apple #{orange} grapes\n)
 => ["apple", "orange", "grapes\n"] 
puts result
apple
orange
grapes

Notice the escape sequence \n caused a newline break after grapes. That would not happen with %w. %w is used for single-quoted array elements. And of course single quoted strings do not support interpolation and escape sequences.

Instead of doing this:

result = [‘a’, ‘b’, ‘c’]

you can do:

result = %w{a b c}

But look what happens when we try this:

result = %w{a b c\n}
 => ["a", "b", "c\\n"] 
puts result
a
b
c\n

Remember do not confuse these constructs with %x (alternative for ` backtick which is used to run unix commands), %r (alternative for // regular expression syntax useful when you have a lot of / characters in your regular expressions and do not want to escape them) and finally %s (which is sued for symbols).

Daniel Viglione
  • 8,014
  • 9
  • 67
  • 101