问题陈述
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. any library intended to provide alternative exception handling will be tied to a specific launcher tool.
- 使REPL异常处理器可动态重绑定
如果REPL异常处理器是一个动态的、线程局部的变量,用户和库就可以更改当前运行REPL的行为。
好处
1. 用户和库可以自由地覆盖异常的打印方式,无论Clojure是如何启动的。
2. 完全与现有工具兼容。
权衡
1. 库的作者将能够提供“错误”或有问题的错误打印机。这仍然可以通过启动工具来实现,但使用库的进入障碍更低。
所附补丁实现了这个选项。
- 鼓励用户启动新的REPL
在许多Clojure环境中,可以从另一个REPL中显式地启动一个REPL。这个子REPL可以具有所需的:捕获钩子。
好处
1. 不需要做出任何努力或更改现有代码。
2. "函数纯粹",并与当前REPL的设计相一致。
权衡
1. exists a non-trivial subset of Clojure developers who do not know exactly how REPLs work. They are likely to be confused or subject to increased cognitive load. To the extent that this set of beginners/intermediate developers are precisely the target group for which enhanced error messages are initially intended to help, this solution is counterproductive.
2. For better or worse, many existing and widely used tools do not support this. For example, it does not work at all in nREPL. However, even the simplest command-line REPL's behavior would change for the worse; sending EOF (accidentally or otherwise) would always kill the sub-REPL without any feedback on what just happened.