问题声明
Clojure的REPL能够参数化其功能的几乎所有方面,包括异常的打印方式。在当前实现中,这些自定义钩子作为参数传递并闭包,意味着一旦启动REPL,就无法更改。
许多开发工具都希望覆盖REPL处理未捕获错误的方式。以下是一些有用的自定义示例(但不仅仅限于此)
- 格式化的异常消息(包括空格和ANSI着色)
- 某些异常类型的替代表示(例如,Spec错误)
- 进入图形交互模式以更好地检查ex-data。
目前,此类自定义必须在启动REPL之前应用,这意味着更改REPL显示错误需要第三方工具(如Boot或Leiningen)的支持。
替代方案
<BR/>
1. 不采取行动。
需要第三方工具支持才能在REPL中创建自定义异常处理。工具有不同的技术来实现这一点
- nREPL可以拦截传递到线上的异常并通过中间件传递
- Leiningen插件修改了{{clojure.main/repl-caught}}的根本绑定。
- Boot允许用户构建一个任务来用所需的参数调用{{clojure.main/repl}}。
用户将继续根据自己的工具偏好选择其中之一。
优点
1. 没有努力或修改现有代码。
权衡
1. 工具将继续实现自己各种不同、有时是陋技的技术来打印自定义异常。
2. 旨在提供替代异常处理的任何库都将与特定启动器工具绑定。
- 使REPL异常处理器动态重新绑定
如果REPL异常处理器是一个动态的、线程局部变量,用户和库就可以改变当前运行的REPL的行为。
优点
1. 用户和库可以自由地覆盖异常的打印方式,而不论Clojure如何启动。
2. 完全与现有工具兼容。
权衡
1. 库作者可以提供“较差”或推论不佳的错误打印机。这也仍然与启动工具一起使用,但与库相比,准入门槛更低。
附带的补丁实现了此选项。
- 鼓励用户启动新的REPL
在许多Clojure环境中,可以从另一个REPL中显式启动REPL。这个子REPL可以具有所需的:caught钩子。
优点
1. 没有努力或修改现有代码。
2. “功能纯粹”,与当前REPL的明显设计一致。
权衡
1. 有一些Clojure开发者并不真正了解REPL的工作原理,这部分人群可能会感到困惑或认知负荷增加。既然这个初学者/中级开发者群体正是错误信息增强措施旨在帮助的对象,那么这种解决方案就适得其反。
2. 好或不好,许多现存的广泛使用的工具都不支持这一点。例如,在nREPL中根本不起作用。然而,即使是简单的命令行REPL行为也会变差;发送EOF(可能是意外或故意)总是会导致子REPL被杀死,没有任何关于刚才发生了什么的反馈。