2017-05-09 9 views
1

Sagen wir, ich habe eine Funktion, die etwas ausführlich ist und mit den gleichen Argumenten jedes Mal aufgerufen wird, diese Funktion ist auch eine Menge Setup erforderlich, bevor andere Funktionen aus diesem Modul aufgerufen werden können sein Rückruf.Elixir - Passing-Funktion Parameter durch

SomeMod.called_a_lot(‘xx’, fn(y) -> 
    SomeMod.needs_called_a_lot_to_be_called_first(‘do_stuff’) 
end) 

Ich stelle mir vor, dass ich es wie so wickeln kann: es

defp easier_to_call(func) do 
    SomeMod.called_a_lot(‘xx’, fn(y) -> func(y) end 
end 

verwenden Sie dann etwa so:

easier_to_call(fn(y) -> 
    SomeMod.needs_called_a_lot_to_be_called_first(‘do_stuff’) 
end) 

Wie macht man tatsächlich tun dies in Elixir?

+1

Ihr Code sieht gut aus; Ändern Sie einfach 'func (y)' in 'func. (y)' da es eine anonyme Funktion ist. – Dogbert

Antwort

1

Ihre Syntax ist nur ein bisschen off für anonyme Funktionen aufrufen. Sie werden

func.(y) 

statt

func(y) 

verwenden müssen, da es sich um eine anonyme Funktion ist.

Siehe das Elixir Crash Course für ein kurzes Beispiel.

1

Dogberts Kommentar ist korrekt. Aber da Sie nicht die Argumente ändern, könnten Sie einfach die Funktion weitergeben, ohne es in einer anonymen Funktion Verpackung:

defp easier_to_call(func) do 
    SomeMod.called_a_lot(‘xx’, func) 
end 
1

Ich verstehe nicht wirklich, was genau Sie fragen, aber ich fühle mich wie die capture operator (&) ist, was Sie suchen.

Ein Beispiel wäre die Verwendung:

easier_func = &SomeMod.called_a_lot(‘xx’, &1) 

easier_func.(fn(_y) -> 
    SomeMod.needs_called_a_lot_to_be_called_first(‘do_stuff’) 
end) 

Mit &1 in der anonymen Funktion der erste Parameter sein.

Wenn Sie eine mehr arity anonyme Funktion benötigt, dann können Sie tun:

easy_reduce = &Enum.reduce(&1, 0, &2) 

easy_reduce.([1,2,3,4], fn(x, acc) -> acc + x end) # => 10 
1

gerade ein anderen Ansatz zeigen: es könnte mit Makro erreicht wird, dass die Funktion zuerst genannt werden ruft und ruft dann den Block :

defmodule Test do 
    defmacro with_prepended(arg, do: block) do 
    quote do 
     IO.inspect(unquote(arg), label: "In function") 
     prepended(unquote(arg)) 
     unquote(block) 
    end 
    end 
end 

defmodule Tester do 
    require Test 

    defp prepended(arg), do: IO.inspect(arg, label: "In prepended") 

    def fun(arg) do 
    Test.with_prepended(arg) do 
     IO.puts "Actual code" 
    end 
    end 
end 

Tester.fun(42) 

#⇒ In function: 42 
#⇒ In prepended: 42 
#⇒ Actual code