Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shortcut for creating Hashes

I am new to Ruby. I'm going through a tutorial on Rubymonk and am just learning how to create hashes. Can you tell me why I can't create a hash without the key_value_pairs variable. It seems logical to my code-resistant brain that the code should work without it, but it doesn't.

This doesn't work

def artax
  a = [:punch, 0]
  b = [:kick, 72]
  c = [:stops_bullets_with_hands, false]

  Hash[a,b,c]
end
p artax

This works.

def artax
  a = [:punch, 0]
  b = [:kick, 72]
  c = [:stops_bullets_with_hands, false]
  key_value_pairs = [a, b, c]
  Hash[key_value_pairs]
end
p artax
like image 540
VaVa Avatar asked Jul 18 '15 12:07

VaVa


2 Answers

Please look at the documentation for Hash::[], there are three ways to call it:

  • with a list of alternating keys and values, like Hash[key1, value1, key2, value2, key3, value3]
  • with a single array, containing arrays containing keys and values, like Hash[[[key1, value1], [key2, value2], [key3, value3]]]
  • with a single object that is convertible to a hash

In the first form, there has to be an even number of arguments, in the second and third form, there has to be exactly one argument.

In your first example, you call it with three arguments, which is neither even nor 1, ergo, it doesn't fall under any of the three forms above. If you had accidentally used four arrays (or two), i.e. an even number, if would have fallen under the first form, but it wouldn't have done what you expect it to:

def artax
  a = [:punch, 0]
  b = [:kick, 72]

  Hash[a, b]
end
p artax
# { [:punch, 0] => [:kick, 72] }

In your second example, you call it with a single array, which falls under the second form.

like image 115
Jörg W Mittag Avatar answered Sep 28 '22 07:09

Jörg W Mittag


To make the first one work, you'd have to write

def artax
  a = [:punch, 0]
  b = [:kick, 72]
  c = [:stops_bullets_with_hands, false]

  Hash[ [a,b,c] ]
end
like image 45
Cyril Duchon-Doris Avatar answered Sep 28 '22 08:09

Cyril Duchon-Doris