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的no-side-effects和lazy特征有关,但目前还没有找到解决方案。非常感谢任何帮助!

谢谢!
j.

共有2个答案

+3

map是lazy的。您可能会通过将(map ...)调用包裹在(doall (map ...))调用中,或者使用(急切的)的mapv来代替map来获得更好的结果。

请注意,在REPL中,REPL的P(打印)部分将迫使lazy的map返回值完全评估,以便可以打印。

by
`doall`是一个安全的多功能快速修复,适用于几乎所有与懒惰相关的难题。但如果返回值不重要(只有副作用重要),则`dorun`会更清晰,而`doseq`则可能更直接且符合习惯。
by
从Clojure 1.7起,我可能在这里会使用run!而不是doseq,因为它的用法与map/mapv完全一样,但它是急切的并且丢弃了每个函数调用的结果。
0
by

你的代码中可能有些东西依赖于你的环境变量。

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

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

by
两个环境的环境变量完全相同...
...