2017-04-08 7 views
1

からのキャプチャ値は、次のコードスニペットを考えてみましょう:エリクシール - ラムダ

def capture 
    Functor.function(fn(value) -> ??? end) 
    ??? 
end 
  • は、ラムダをキャプチャするための好ましい方法だろう何

確実に1回だけ呼び出さ取得していると仮定しますラムダfn(value)の最初の引数は、それはcaptureメソッドの返品になることができる方法で?

+0

私はこの質問をよく理解しています。あなたは 'キャプチャ'から 'value'を返そうとしていますか? fnが一度でも呼び出されないとどうなるでしょうか?そのfnが複数回呼び出されるとどうなるでしょうか? – Dogbert

+1

@Dogbertあなたが提起した問題を明確にしようと、フィードバックのおかげで!あなたのニックを愛して;) – Kalecser

答えて

4

ここでは、何らかの形の可変状態が必要です。

defmodule Functor do 
    def function(f) do 
    f.(:hey) 
    end 

    def capture do 
    {:ok, agent} = Agent.start_link(fn -> nil end) 
    Functor.function(fn(value) -> 
     Agent.update(agent, fn _ -> value end) 
    end) 
    Agent.get(agent, &(&1)) 
    end 
end 

IO.inspect Functor.capture() 

出力:

:hey 

いくつかの点に注意する:

をFNが呼び出されない場合は、エージェントの初期値を取得します最も簡単な方法は、Agentを使用することです(上記コードのnil)。

fnが複数回呼び出された場合は、最後の呼び出しの値が取得されます。少し変更するだけで、すべて値をキャプチャすることもできます。


編集:あなたが唯一のテストのためにこれを使用している言及したので、他にはあります、はるかに簡潔な方法。 fnからあなた自身にメッセージを送ってassert_receiveと表明してください:

test "the truth" do 
    pid = self() 
    Functor.function(&send(pid, &1)) 
    assert_receive :hey 
end 
+0

素晴らしい答えをありがとう!私はすでにエージェントを使っていましたが、それを行うための好ましい方法について確かめたいと思っていました。私たちは現在、単体テストのみを記述するためにこのテクニックを使用しています。これを実際に本番環境で使用することはほとんどありません。 – Kalecser

+2

これがテストのためのものであれば、より良い/短く私の編集をご覧ください! – Dogbert

+0

本当に単純なケースのために、ありがとうございます。assert_receiveが推奨されるソリューションになります。 ;) – Kalecser

関連する問題