Skip to content

Instantly share code, notes, and snippets.

@adsteel
Last active August 29, 2015 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adsteel/b221944019ee77890f81 to your computer and use it in GitHub Desktop.
Save adsteel/b221944019ee77890f81 to your computer and use it in GitHub Desktop.
Splat and Double Splat

##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"...
                                      ^

Singles to the left, please

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment