##Order Dependencies in Ruby's Splat & Double Splat Arguments
Ruby's splat and double splat arguments allow for some pretty flexible coding.
def print_arguments(*single, **double)
p single
p double
end
print_arguments("cow", "sheep", "boat", username: "username", password: "password")
["cow", "sheep", "boat"]
{:username=>"username", :password=>"password"}
Keen gear. However, there are some order dependencies here. Ruby will not magically know to collect all key-value pairs into **double and all single values into *single.
print_arguments("cow", "sheep", tree: "maple", "boat", username: "username", password: "password")
#=> syntax error, unexpected ',', expecting =>
..."cow", farmer: "jane", "sheep", "boat", username: "username"...
^
In fact, it looks like we need to separate our arguments into single value and key-value types, and the single values and the single splat need to be on the left.
def print_arguments(one, two, *single, three:, four:, **double)
p one
p two
p three
p four
p single
p double
end
print_arguments("cow", "sheep", "boat", three: "tree", four: "plant", username: "username", password: "password")
"cow"
"sheep"
"tree"
"plant"
["boat"]
{:username=>"username", :password=>"password"}
##Singles mingle, pairs don't If you have a need to move your splats and double splats around, Ruby can accommodate that with a single splat, but not a double splat.
# single splat arguments can sit in the middle of other single arguments
def print_arguments(one, *single, two); ...; end
# but double splats must be at the end of the argument list
def print_arguments(:one, :two, **double); ...; end
# This will not work :(
def print_arguments(one, two, three:, four:, *single, **double)
...
end
# Nor will this work
def print_arguments(three:, four:, **double, one, two, *single)
...
end
Maybe some day Ruby will fix this order dependency, but until then, splat and double splat arguments will still be awesome.