Ruby's Double Splat Operator
Open up an IRB console and follow along with me.
It can be confusing
The double splat never ceases to confuse me:
# which of the following methods are correct?
# open an irb and try it out, if you don't know.
def ds_1(**hash) # correct?
hash
end
def ds_2(hash**) # or is this correct?
hash
end
# ds_1 is correct
# ds_2 is wrong
#_______________________
# Which one is correct?
h = {a: "a", b: "b"}
ds_1(h) # can I do this?
ds_1(**h) # will this work?
# ds_1(h) will not work.
# ds_1(**h) will work
# Is it just me or it is slightly tricky?
The tricky part is that the double splat can be used both as an argument passed in, and also in a method definition.
def ds_3(**hash)
hash
end
h = {a: "a", b: "b"}
ds_3(a: "a")
# => {a: "a"}
ds_3(a: "a", b: "b")
# => {:a=>"a", :b=>"b"}
# what do you think will happen here?
ds_3(h) # What do you think will happen here?
# => irb):22:in `ds_3': wrong number of arguments (given 1, expected 0) (ArgumentError)
## Oops!
# How can we make it work?
ds_3(**h)
# => {:a=>"a", :b=>"b"}
Wait, so double splat can be used as a parameter in a method, and also as an argument passed into a method?
Yep.
**h
essentially destructures a hash.
**h
# => <top (required)>': (irb):20: syntax error, unexpected **arg (SyntaxError)
# but it will work in a hash
{**h}
# => {:a=>"a", :b=>"b"}
Consider:
def ds_3(**hash) # This turns keyword arguments into a hash
hash
end
hash_1 = {:a=>"a", :b=>"b"}
ds_3(**hash_1) # and this turns a hash into key words
# But we can do interesting things:
def ds_4(a: , **hash)
puts "a is #{a}, hash is: #{hash}"
end
ds_4(hash_1) # what do you expect?
# => `ds_4': wrong number of arguments (given 1, expected 0; required keyword: a) (ArgumentError)
ds_4(a: 1, hash_1)
# Nope. syntax error
ds_4(a: 1, b: 2)
# => a is 1, hash is: {:b=>2}
ds_4(a: 1, **hash_1) # what do you expect
# a is 1, hash is: {:b=>"b"} or:
# a is a, hash is: {:b=>"b"}
# the answer is the latter.
ds_4(a: 1, **hash_1)
# => a is a, hash is: {:b=>"b"}
ds_4(a: 1, a: "a")
# => a is a, hash is: {} (and you also have a duplicate key warning)
Written on December 6, 2024