Elixir 长生不老药-从lambda获取价值

Elixir 长生不老药-从lambda获取价值,elixir,Elixir,考虑以下代码段: def capture Functor.function(fn(value) -> ??? end) ??? end 假设lambda确实被调用了一次 捕获lambdafn(value)的第一个参数的首选方法是什么,它可以是capture方法的返回?这里需要某种形式的可变状态。最简单的方法是使用代理: defmodule Functor do def function(f) do f.(:hey) end def capture

考虑以下代码段:

def capture
    Functor.function(fn(value) -> ??? end)
    ???
end
  • 假设lambda确实被调用了一次

捕获lambda
fn(value)
的第一个参数的首选方法是什么,它可以是
capture
方法的返回?

这里需要某种形式的可变状态。最简单的方法是使用
代理

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\u receive
进行断言:

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

这里需要某种形式的可变状态。最简单的方法是使用
代理

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\u receive
进行断言:

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

我不确定我是否理解这个问题。是否要从
capture
返回
?如果fn连一次都不打电话怎么办?如果fn不止一次被呼叫怎么办?@Dogbert试图澄清您提出的问题,谢谢您的反馈!爱你的尼克;)我不确定我是否理解这个问题。是否要从
capture
返回
?如果fn连一次都不打电话怎么办?如果fn不止一次被呼叫怎么办?@Dogbert试图澄清您提出的问题,谢谢您的反馈!爱你的尼克;)谢谢你的回答!我已经在使用代理了,但我想确定使用哪种方法更合适。我们目前仅将此技术用于编写单元测试-据我所知,我们很少在生产中使用此技术。如果此技术仅用于测试,请参阅我的编辑,以获得更好/更短的方法!感谢您的更新,事实上对于简单的案例,assert_receive将是首选解决方案。;)谢谢你的回答!我已经在使用代理了,但我想确定使用哪种方法更合适。我们目前仅将此技术用于编写单元测试-据我所知,我们很少在生产中使用此技术。如果此技术仅用于测试,请参阅我的编辑,以获得更好/更短的方法!感谢您的更新,事实上对于简单的案例,assert_receive将是首选解决方案。;)