2024 Clojure 发展调查 中分享你的想法!

欢迎!请查看 关于 页面以了解此网站的工作原理。

0
REPL

大家好,

我有一个脚本,使用 monger 库更新 MongoDB 数据库中的数据。当我打开 repl 并粘贴代码时,所有更新都会执行,但我无法使用 lein run 使其工作。

相关代码

(ns covid-data-management.core
(:require [oz.core :as oz]
                  [monger.core :as mg]
                  [monger.collection :as mc]))
(defonce db (mg/get-db (mg/connect) "covid19"))
(def coll "surveys")
(defn update-symptoms []
    (println "In the update-symptoms definitions")
    (map (fn [x]
            (mc/update db coll {} {"$set" {:symptoms ["symptom1" "symptom2"]}}))))

(defn main [& args]
    (update-symptoms))

在 REPL 中粘贴代码正好执行它应该做的事情:设置新的症状。当使用 lein run 运行时,控制台打印出字符串 "在 update-symptoms 定义中",但数据库本身并没有被更改。

我怀疑这与 Clojure 的无副作用和延迟功能有关,但我还没有找到解决方案。任何帮助都欢迎!

谢谢,
j.

2 个回答

+3

map 是惰性的。你可能需要将 (map ...) 调用包裹在 (doall (map ...)) 调用中,或者如果你使用 mapv(它是急切的)而不是 map,你可能会得到更好的结果。

请注意,在 REPL 中,REPL 的 P(打印)部分会强制从 map 获取的惰性返回值进行完全评估,以便可以将其打印出来。

`doall` 是一个安全的通用快速修复方法,适用于解决几乎所有与惰性有关的问题。但是,如果返回值不重要(只有副作用重要),则 `dorun` 可能更清晰,而 `doseq` 可能更直接和惯用。
自从 Clojure 1.7 以来,我可能在这里会使用 run! 而不是 doseq,因为用法与 map/mapv 完全相同,但它是急切执行的并且丢弃每个函数调用的结果。
0

你的代码中可能有部分代码依赖于你的环境变量。

你的 REPL 环境 与 lein run 环境相同吗?

你可以使用 (prn (System/getenv)) 来进行调试

两者的环境变量完全相同...
...