Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use splat operator to create a Hash?

Tags:

ruby

I'm following the RubyMonk tutorial. There is a part that deals with the splat operator, and how you can use it with a Hash. This is valid code:

puts Hash[4, 8]
puts Hash[ [[4, 8], [15, 16]] ]

But then it says that you can also use:

ary = [[4, 8], [15, 16], [23, 42]]
puts Hash[*ary.flatten]

Why would anyone use this last form of creating a Hash, with flatten, instead of just doing Hash[ary] directly?

like image 636
evianpring Avatar asked Jan 07 '23 15:01

evianpring


2 Answers

There are a few ways you can initialize a hash. You can pass it array of pairs or just list the keys and values. Examples from documentation:

Hash["a", 100, "b", 200]             #=> {"a"=>100, "b"=>200}
Hash[ [ ["a", 100], ["b", 200] ] ]   #=> {"a"=>100, "b"=>200}

Note that there is no form that accepts a one-level array. It's either array of arrays or no array at all. The splat is needed to "expand" that flattened array into simple argument list (thus, making it behave like the first form in your example)

Depending on ruby version, this will either return an empty hash or raise an error.

RUBY_VERSION # => "2.1.5"
ary = [[4, 8], [15, 16], [23, 42]].flatten
ary # => [4, 8, 15, 16, 23, 42]
Hash[ary] # => {} # !> this causes ArgumentError in the next release

It obviously doesn't make sense to do *ary.flatten (just use ary), but you might get this flat array from elsewhere. That's when you'll need to splat it.

like image 119
Sergio Tulentsev Avatar answered Jan 18 '23 20:01

Sergio Tulentsev


One difference between Hash[ary] and Hash[*ary.flatten] is the behavior if the array can't be turned into a hash cleanly. Consider, for instance, this object:

# ary now contains an array with more than two values
ary = [[4, 8, 9], [15, 16], [23, 42]]

# Calling Hash[ary] will succeed by ignoring the invalid array
puts Hash[ary] # => {15=>16, 23=>42}

# Calling Hash[*ary.flatten] will return the expected error
puts Hash[*ary.flatten]
# => class: ArgumentError
# => message: odd number of arguments for Hash
# => backtrace: RubyMonk:4:in `[]'

If you're trying to understand what the splat is actually doing for you I strongly recommend this article (it's not very recent, but still very applicable).

https://endofline.wordpress.com/2011/01/21/the-strange-ruby-splat/

like image 26
ConnorCMcKee Avatar answered Jan 18 '23 19:01

ConnorCMcKee