Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prefer %w(...) to a literal array? [closed]

Tags:

ruby

While entering a simple literal array of strings in to RubyMine:

cols = [   "Col1",   "Col2" ] 

RubyMine complained that I should prefer to use %w over a literal array:

cols = %w(Col1 Col2) 

It presented a link to a Ruby Style Guide (here), which said:

Prefer %w to the literal array syntax when you need an array of strings.

# bad STATES = ['draft', 'open', 'closed']  # good STATES = %w(draft open closed) 

I can see how the %w provides potentially more concise code. Aside from brevity, is there any reason to prefer one method over the other?

like image 551
John Dibling Avatar asked Oct 23 '12 19:10

John Dibling


People also ask

What does %w mean 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.

What is a literal array?

An array literal is a list of zero or more expressions, each of which represents an array element, enclosed in square brackets ( [] ). When you create an array using an array literal, it is initialized with the specified values as its elements, and its length is set to the number of arguments specified.

Are strings arrays in Ruby?

With a Ruby string array, we can store many strings together. We often prefer iterators, not loops, to access an array's individual elements. In Ruby programs, we use string arrays in many places.


Video Answer


1 Answers

Voila!, one benchmark:

require 'benchmark'  n = 1_000_000 Benchmark.bm(11) do |b|   b.report('%w') { n.times { %w[a b c d e f g h i j k l m n o p q r s t u v w x y z] } }   b.report('explicit') { n.times { ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'] } }   b.report('numerics') { n.times { [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26] } } end                    user     system      total        real %w            2.590000   0.000000   2.590000 (  2.591225) explicit      2.590000   0.000000   2.590000 (  2.584781) numerics      0.300000   0.000000   0.300000 (  0.309161)                    user     system      total        real %w            2.590000   0.000000   2.590000 (  2.591516) explicit      2.590000   0.000000   2.590000 (  2.584155) numerics      0.300000   0.000000   0.300000 (  0.308896)                    user     system      total        real %w            2.590000   0.000000   2.590000 (  2.592848) explicit      2.590000   0.000000   2.590000 (  2.585558) numerics      0.300000   0.000000   0.300000 (  0.308570) 

I added the "numerics" array test because I suspected that %w is faster than using explicit strings due to testing for stringiness. %w doesn't need to do that, because it assumes everything is a string. After running it three times it's a wash as far as dealing with strings. Numbers rule, strings drool, and all that.


The previous benchmarks were run using Ruby 1.9.3-p286 on my system at work. I tested again using my old MacBook Pro at home, using Ruby 1.8.7-p358, so the following numbers are slower due to the differences in the hosting hardware, plus running an older Ruby:

                user     system      total        real %w           3.070000   0.000000   3.070000 (  3.080983) explicit     3.100000   0.000000   3.100000 (  3.093083) numerics     0.950000   0.040000   0.990000 (  0.990535)                  user     system      total        real %w           3.080000   0.010000   3.090000 (  3.076787) explicit     3.090000   0.000000   3.090000 (  3.089246) numerics     0.950000   0.030000   0.980000 (  0.989579)                  user     system      total        real %w           3.080000   0.000000   3.080000 (  3.073877) explicit     3.090000   0.000000   3.090000 (  3.091576) numerics     0.950000   0.030000   0.980000 (  0.989132) 

On 1.8.7, %w was a tiny bit faster consistently, which probably gave rise to the speed-rumors.

like image 190
the Tin Man Avatar answered Sep 20 '22 09:09

the Tin Man