问题
为程序入口点添加自定义行为是有用的。此类行为的示例
- 调用(shutdown-agents)
以确保优雅关闭;
- JavaFX应用程序中调用(Platform/exit)
以确保优雅关闭;
- 在测试运行器中将System/out
和System/err
重新绑定以收集所有的输出。
-main
函数是-M
-样式入口点的自然位置来放置这些行为。
这些行为的一个特性是,它们可能对入口点非常有用,但它们以某种方式影响JVM,以至于这些程序可能无法集成到长时间运行的程序中。
对于-X
-可调用函数的情况,这种特性是存在问题的,因为它们应该既作为入口点调用,又作为用户依赖项调用并长时间运行程序的一部分调用,但没有方法区分它们。
考虑的解决方案
- 不采取行动。库作者可以在他们的
-X
-可调用函数中添加可选参数来禁用特殊的入口点行为,尽管如果它们的程序以意外方式调用用户代码时出现问题时,这也可能令用户烦恼。库作者可以添加可选参数来启用特殊的入口点行为,而不是禁用它,但这使得库在命令行上的使用更加不便。库作者可以为命令行和用户代码创建单独的-X
-可调用函数,但这降低了在整个API中有相同命令行工具的想法的有用性。
- 使用clj-exec向
-X
样式调用提供额外的参数,这暗示它是作为入口点调用的,例如:clj -X clojure.core/prn :a 1
将打印{:entry-point true :a 1}
。我认为这种行为是意外的,可能会令人困惑,甚至可能令人烦恼。
-X
可调用变量可以定义将在作为入口点调用时添加到参数中的元数据,例如:
(defn ^{:default-clj-exec-argmap {:rebind-system-err true}} do-stuff [argmap] ...)
然后,运行clj -X my.ns/do-stuff :other :args
将使用{:rebind-system-err true}
作为默认的argmap,然后将其与其他参数合并。