Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use a tuple as arguments for a function in Elixir

I'm writing a game engine in Elixir. (Yes, I know it's not a language inherently suited to that – the point is to look at how the use of an atypical language affects the structure of the result.)

As such, I have several supervisors to be run on game start – but what exactly they should be supervising depends on the game. My thought had been to have the user list out the necessary children, plus arguments and options, in the config.exs file as a list of tuples, and then the supervisor itself would simply pull those tuples from the application environment and use their contents as arguments to worker\2 (or worker\3, as appropriate).

However, I can't find any Elixir equivalent to Python's tuple-unpacking. I could do it myself for this specific case with a simple function:

def unpack_worker({module, args}) do
  worker(module, args)
end

def unpack_worker({module, args, opts}) do
  worker(module, args, opts)
end

But that feels clumsy at best, and would have to be written again for every function for which I might need this kind of configurability.

like image 538
Vivian Avatar asked Apr 13 '26 17:04

Vivian


2 Answers

I believe you're looking for Tuple.to_list/1 and apply/3:

With those, you can invoke a function of the correct arity based on the contents of the tuple:

def unpack_worker(args) do
  apply(__MODULE__, :worker, Tuple.to_list(args))
end

If you now call unpack_worker({}), it'll call worker(), unpack_worker({:foo}) will call worker(:foo), and so on.

Demo:

defmodule A do
  def worker, do: IO.puts 0
  def worker(_), do: IO.puts 1
  def worker(_, _), do: IO.puts 2
  def worker(_, _, _), do: IO.puts 3

  def unpack_worker(tuple), do: apply(__MODULE__, :worker, Tuple.to_list(tuple))
end

A.unpack_worker({})
A.unpack_worker({:a})
A.unpack_worker({:a, :b})
A.unpack_worker({:a, :b, :c})

Output:

0
1
2
3
like image 67
Dogbert Avatar answered Apr 17 '26 12:04

Dogbert


I think you need to know the size of a tuple to properly access the elements. Maybe a better data structure for your use case would be a keyword list, especially considering it's what you get from config anyway? Then you can unpack worker:, args: and leave the remainder as options?

like image 28
Elfred Avatar answered Apr 17 '26 13:04

Elfred



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!