Есть ли в Elixir оператор splat?
defmodule UnixCommands do
alias Porcelain.Result
def run(command, *opts) do
%Result{out: output, status: _} = Porcelain.exec(command, [opts])
IO.puts output
end
end
Существует ли эквивалент оператора splat, например * opts, в Elixir?
Есть ли способ передать несколько опций вместо списка параметров функции exec в качестве аргументов?
Ответы
Ответ 1
Нет оператора splat. Функции в Elixir (и Erlang) определяются их именем и arity (String.downcase/1
, Enum.member?/2
), и вариационная функция будет идти против этого.
Об этом говорит один из авторов Erlang Joe Armstrong в его книге "Программирование Erlang: программное обеспечение для параллельного мира":
1) функция arity является частью ее имени и
2) нет вариационных функций.
Если вы хотите вызвать функцию со списком аргументов (напротив того, что вы хотите), можете использовать Kernel.apply/3.
например.
defmodule Test do
def add(a, b, c) do
a + b + c
end
end
apply(Test, :add, [1, 2, 3])
Ответ 2
Вы не можете указать переменную arity для функций в Elixir (или Erlang, если на то пошло), как сказал Газир. Проще всего сделать, чтобы передать список вместо параметра, который вы хотите изменить по числу, а затем использовать сопоставление образцов, чтобы разложить его должным образом. Учитывая ваш пример выше, он будет выглядеть следующим образом:
defmodule UnixCommands do
alias Porcelain.Result
def run(command,[opts]) do
optlist = opts |> Enum.reduce(fn o-> "#{o} " end)
%Result{out: output, status: _} = Porcelain.exec(command, optlist)
end
end
NB: я не тестировал этот код, потому что я не хочу устанавливать Porcelain, но он должен быть в основном правильным.