1

Possible Duplicate:
What is the * operator doing to this string in Ruby

I ran across the following code when looking for an easy way to convert an array to a hash (similar to .Net's ToDictionary method on IEnumerable... I wanted to be able to arbitrarily set the key and the value).

a = [ 1, 2, 3, 4, 5, 6 ]
h = Hash[ *a.collect { |v| [ v, v ] }.flatten ]

My question is, what does the asterisk before a.collect do?

By the way, the code comes from http://justatheory.com/computers/programming/ruby/array_to_hash_one_liner.html

Community
  • 1
  • 1
Eric Andres
  • 3,417
  • 2
  • 24
  • 40
  • Ah, hadn't found that one yet. The asterisk is tricky to search for because google and SO filter it out of searches. – Eric Andres Feb 28 '12 at 22:08
  • Well, now you know it’s called “splat”. :-) – Josh Lee Feb 28 '12 at 22:10
  • 2
    The Symbol Hound search engine specializes in searching for symbols: [`ruby *`](http://symbolhound.com/?q=ruby%20%2A) – sarnold Feb 28 '12 at 22:12
  • 1
    Thanks @sarnold, I'd never heard of Symbol Hound before. I'll have to remember it in the future. – Eric Andres Feb 28 '12 at 22:16
  • NB: the splat [non-]operator has the lowest precedence in the example code, so it is working on the result of this: `a.collect { |v| [ v, v ] }.flatten` which is an array. the point of the splat [non-]operator in the expression is that it converts that array to a list which can then be passed to Hash[]. This is necessary because, e.g. Hash[1, 2, 3, 4] works, but Hash[[1, 2, 3, 4]] does not. Note that Hash[*[1, 2, 3, 4]] is equivalent to Hash[1, 2, 3, 4]. – John M Naglick Oct 22 '15 at 19:46

1 Answers1

4

It's the splat-operator if you want to google it. It does transform an array into a list (so you can use an array as arguments to a method). It also does the opposite: it can 'slurp' a list into an array.

require 'date'
*date_stuff = 2012,2,29 # slurp
p date_stuff #=> [2012, 2, 29]
Date.new(*date_stuff) # regurgitate
steenslag
  • 79,051
  • 16
  • 138
  • 171
  • Thanks for the bonus info on the opposite behavior. – Eric Andres Feb 28 '12 at 22:17
  • isn't `a, b = *[:one, :two]` called a tuple in general programming? – farnoy Feb 28 '12 at 22:35
  • @fanoy - I know nothing about tuples in general programming. Your code works; it even works without the splat (which is kinda strange). – steenslag Feb 28 '12 at 23:12
  • The splat is not necessary in your first example; Ruby lets you omit the brackets when defining an array. You probably wanted something like `first, *middle, last = 1,2,3,4,5; p middle #=> [2, 3, 4]` – Kaia Leahy Jul 13 '17 at 13:58