从命令行运行clojure jar的不一致

时间:2011-12-04 11:49:47

标签: jdbc clojure read-eval-print-loop

我有一个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函数并正确更新表。

2 个答案:

答案 0 :(得分:4)

如果这在REPL中起作用,但在单独执行时不起作用,那么我猜你可能会被Clojure的懒惰所困扰。

您的代码是否需要doseq才能获得副作用(例如写入数据库)?

答案 1 :(得分:0)

钉了它。这是我程序中一个非常阴险的错误。我被clojure的懒惰所咬。 我的文件树函数在内部使用了map,因此只产生了第一个值,即根目录。出于某种原因,我仍然无法弄清楚,当在REPL执行时,评估实际上是强制的,并且产生了整个树seq。我刚刚在我的函数中添加了doall并解决了它。

仍然试图弄清楚为什么在REPL执行某些事情的力量评估。有什么想法吗?