2017-04-08 66 views
1

捕捉價值請看下面的代碼片段:藥劑 - 從拉姆達

def capture 
    Functor.function(fn(value) -> ??? end) 
    ??? 
end 
  • 假設拉姆達不會獲取調用一次肯定

什麼是捕捉到的首選方式lambda fn(value)的第一個參數在某種程度上可以返回capture方法嗎?

+0

不知道我明白這個問題。你想從'capture'返回'value'?如果該fn不被稱爲一次,該怎麼辦?如果這個fn被稱爲不止一次呢? – Dogbert

+1

@Dogbert試圖澄清你提出的問題,謝謝你的反饋!愛你的暱稱;) – Kalecser

回答

4

這裏你需要某種形式的可變狀態。最簡單的方法是使用Agent

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永遠不會被調用,你會得到代理的初始值(在上面的代碼中爲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