DEV Community

loading...
JetRockets

Double splat arguments in Crystal

Igor Alexandrov
Originally published at jetrockets.pro Updated on ・1 min read

In Crystal, as well as in Ruby you can use double splat arguments. Unfortunately they behave a bit different.

def foo(**options)
  baz(**options, a: 1)
end

def baz(**options)
  puts options
end

foo(b: 2, a: 3) # {:b=>2, :a=>1} 

This code in Ruby works as it should. If we try the same in Crystal (https://play.crystal-lang.org/#/r/7r0l), we got an error:

error in line 2
Error: duplicate key: a

This happens because **options is a NamedTuple and it cannot have duplicate keys. I found that using NamedTuple#merge can be a workaround (https://play.crystal-lang.org/#/r/7s1c):

def foo(**options)
  baz(**options.merge(a: 1))
end

def baz(**options)
  puts options
end


foo(b: 2, a: 3) # {:b=>2, :a=>1} 

Hack!

Discussion (2)

Collapse
bew profile image
Benoit de Chezelles

Hey, just to tell you that the two shared play links and code blocks are exactly the same, where I think you wanted to show the fixed example code..

Collapse
igor_alexandrov profile image
Igor Alexandrov Author

Fixed. Thank you!