【发布时间】:2013-03-16 19:50:57
【问题描述】:
我对 Clojure 相当陌生,并且正在尝试并行化对函数的一些调用。
假设我有一张如下地图:
{:a 1 :b 2 :c 3}
我想将键和值用作名为 my-function 的函数的参数,该函数为每个键/值对调用。我可以使用doseq 如下:
(doseq [entry my-map] (my-function (key entry) (val entry)))
然后我决定我希望对 my-function 的调用是并行的(在我的实际情况下,my-function 将进行彼此独立的休息调用,因此我想并行执行它们)。我想出了以下几点:
(apply pcalls (map #(partial my-function (key %) (val %)) my-map))
这似乎按我的预期工作(如果我错了或有更好的方法,请纠正我)。我现在遇到的麻烦是让我的 Midje 测试通过。如果我使用上面的doseq 版本,它们会正确通过。在我的测试中,我使用 (provided .... ) 来确保进行正确的调用,并且我希望使用它来检查对 my-function 的调用。是否有可能做到这一点?我发现很难找到有关 pcall 的大量信息。
谢谢
--------- 编辑 ---------
我设计了一个演示失败的示例。
实现可以在here 找到,测试可以在here 找到。我发现单个测试运行良好,但多个测试会导致以下情况:
FAIL at (pcalls_unit.clj:29) 这些调用不正确 次数: (my-func 2 2) [预计至少一次,实际上从未调用过]
在 (pcalls_unit.clj:26) 处“测试一些 pcall 3”失败 预期:无 实际:java.util.concurrent.ExecutionException:java.lang.Error:您似乎已经为 pcalls-test.pcalls/my-func 会干扰该函数在 Midje自己的代码。要修复,请定义一个您自己的函数,该函数使用 my-func,然后在提供的子句中描述该函数。
【问题讨论】:
-
你的测试是什么样的?问题可能在于 Midje 期望结果以特定顺序出现。
-
嗨。我的测试看起来像:(事实“测试某些东西”(method-that-calls-pcalls-stuff-and-more arg1 arg2 arg3)=> {:status 200}(提供(my-function key1 val1)=> some- result1 (my-function key2 val2) => some-result2))
-
你能链接到一个失败的测试的要点吗?请添加失败输出。
-
Midje 应该要求对所有惰性序列进行全面评估(与
doall一样),但可能存在错误。您可以尝试使用doall包装实际值的计算: (fact (doall (computation)) => expected (provided ...) -
感谢您的回复布赖恩。我已经将计算包含在 doall 中,但我得到了相同的失败 - (my-func arg1 arg2) [预期:times 1,实际上称为零次] 出现的并不总是相同的,有时只有 2 个失败,有时 3 个,有时是 4 等等。如果我使用 doall 和 pmap 如下 Arthur 的回答,我会收到一个错误,说明我的函数会干扰该函数在 Midje 自己的代码中的使用