2017-04-08 34 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