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运行时,控制台打印出字符串"In the update-symptoms definitions",但数据库本身并没有改变。

我怀疑这与clojure的无副作用和惰性特性有关,但还没有找到解决方案。非常感谢任何帮助!

谢谢,
j.

2 个回答

+3

map是惰性的。你可能需要在(map ...)调用周围包裹(doall (map ...))调用,或使用惰性的map(使用mapv代替map)来获得更好的效果。

注意,在REPL中,REPL的P(打印)部分会强制map的惰性返回值被完全评估以便打印。

by
`doall` 是一个安全的多用途快速修复,可以解决几乎所有与惰性相关的问题。但是,如果返回值不重要(只有副作用重要),使用 `dorun` 会更清晰,而 `doseq` 可以更直接和高雅。
by
从 Clojure 1.7 开始,我可能会在这里使用 run! 而不是 doseq,因为它的用法与 map/mapv 完全相同,但它是激进的,并且丢弃了每次函数调用的结果。
0
by

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

你的 REPL 环境与你的 lein run 环境是否相同?

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

by
环境对两者都完全相同...
...