Easiest way to convert an array of strings to a splattable tuple?

Hello, I’m writing a small command-line based crystal program but I’ve run into a small problem. After parsing some command line options using OptionParser I want to call a method that takes a variable number of parameters:

my_args = ["my", "args", "from", "command", "line"]

def my_meth(*args : String)
    # do stuff with args
end

Coming from ruby, I kind of expected the array to be “splattable”, but reading the docs it seems like only a Tuple can be “splatted”. But I cannot find a simple way to convert my array to a tuple. There probably is a simple solution, but I can’t find it in the standard library docs or the crystal book.

Any suggestions on how to solve this problem?

Kind regards

Lars

If the array of args is dynamically sized, then you just cannot do it. Maybe update your method signature to be like args : Enumerable(String) and just pass the array directly?

If the size of the array is known at compile time, you could leverage Tuple(*T) - Crystal 1.9.2, but I don’t think that’ll be the case here.

Thank you for the quick answer.

Since I’m getting the arguments from the command line I have no control over how many arguments I get, At the same time I don’t want to force callers of the method to wrap a single string in an array. If an array cannot be splatted and it is impossible to convert the array to a tuple it is probably just easier to overload the function.

def my_meth(arg : String)
    my_meth([arg])
end

def my_meth(args : Enumerable(String))
    # Do stuff with args
end

Lars

Yes, you could also support both of your use cases via like:

def foo(*args : String)
  foo args
end

def foo(args : Enumerable(String))
    # Do stuff with args
end

Such that you could do:

foo "blah"
foo "bar", "baz"
foo({"a", "b", "c"})
foo(["a", "b", "c"])
foo(some_iterator)
1 Like