我有一个clojure程序,在某些时候执行一个名为db-rebuild-files-table
的函数。
此函数将目录文件名作为单个字符串参数,并调用递归函数,该函数下降到目录文件树中,从那里的文件中提取某些数据并将每个文件记录在mysql数据库中。此命令的最终结果是“文件”表,该表由给定目录下树中的所有文件填充。
我需要的是能够定期从shell运行此命令。
所以,我在包含实际调用:gen-class
的{{1}}函数的文件中添加了-main
指令。我运行(db-rebuild-files-table *dirname*)
并生成一个jar,然后我可以执行:
lein uberjar
果然,该函数运行,但在数据库中只存在一个条目*目录* dirname *。当我在clojure REPL中执行完全相同的sexp时,我得到正确的行为: * dirname *下的所有文件树得到处理。
我做错了什么?为什么调用java -jar my-project-SNAPSHOT-1.0.0-standalone.jar namespace.containing.main
在从REPL调用时和从命令行执行时表现不一致?
[编辑]甚至更奇怪的是我在任何地方都没有错误。所有函数调用似乎都可以正常工作。我甚至可以在REPL中运行-main函数并正确更新表。
答案 0 :(得分:4)
如果这在REPL中起作用,但在单独执行时不起作用,那么我猜你可能会被Clojure的懒惰所困扰。
您的代码是否需要doseq
才能获得副作用(例如写入数据库)?
答案 1 :(得分:0)
钉了它。这是我程序中一个非常阴险的错误。我被clojure的懒惰所咬。
我的文件树函数在内部使用了map,因此只产生了第一个值,即根目录。出于某种原因,我仍然无法弄清楚,当在REPL执行时,评估实际上是强制的,并且产生了整个树seq。我刚刚在我的函数中添加了doall
并解决了它。
仍然试图弄清楚为什么在REPL执行某些事情的力量评估。有什么想法吗?