I have no idea if this is a Hash issue or an Array issue, but I don’t figure out why asterisk (*) sign is required in the third example to get a hash filled with data. Without it, it outputs an empty hash.
# -*- coding: utf-8 -*-
require 'pp'
pp [[:first_name, 'Shane'], [:last_name, 'Harvie']]
# => [[:first_name, "Shane"], [:last_name, "Harvie"]]
pp [[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten
# => [:first_name, "Shane", :last_name, "Harvie"]
pp Hash[*[[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten]
# => {:first_name=>"Shane", :last_name=>"Harvie"}
pp Hash[[[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten]
# => {}
Below is an explanation of the method.
--------------------------------------------------------------- Hash::[]
Hash[ [key =>|, value]* ] => hash
From Ruby 1.8
------------------------------------------------------------------------
Creates a new hash populated with the given objects. Equivalent to
the literal +{ _key_, _value_, ... }+. Keys and values occur in
pairs, so there must be an even number of arguments.
Hash["a", 100, "b", 200] #=> {"a"=>100, "b"=>200}
Hash["a" => 100, "b" => 200] #=> {"a"=>100, "b"=>200}
{ "a" => 100, "b" => 200 } #=> {"a"=>100, "b"=>200}
The splat operator (that is, the
*) turns what would otherwise be an array into a list for assignment within the hash. You have to give the[]operator an actual list to turn into the key/value pairs of a hash. See below for a link to a short description of the splat operator which actually can do this (unwind an array into a list) or the reverse (gather a list into an array).The way you did it above, you give
Hash[]an odd number of items, namely a single array. (Think of what[[:first_name, 'Shane'], [:last_name, 'Harvie']].flattenproduces. It yields[:first_name, 'Shane', :last_name, 'Havie'].) As the docs you quoted say, the[]operator must have an even number of elements. Note that the following (though useless) does work:(It’s unclear to me why you don’t get the "odd number of arguments for Hash" error when using the code you have above – as you do if you try
Hash[1].)A simpler example may make it clearer. First, passing in one item, an array. The opening up the array with
*to handHash[]a list of items:You might also find this write-up about the splat operator and the double splat operator useful.