分享您的想法,请参加2024年Clojure状态调查!

欢迎!请查看关于页面以获取更多关于此工作方式的信息。

0
ClojureScript

目前ExceptionInfo以原始构造函数形式实现,继承自js/Error,并添加了一些临时的javascript级别修复以满足deftype功能的一小部分(主要是用于打印)。

不幸的是,这与 cljs-devtools(链接:1)不兼容。当我开始尝试ExceptionInfo和cljs-devtools v0.8(它新支持打印deftype,链接:2)时,这个问题出现了。ExceptionInfo不包含getBasis、cljs$lang$type、cljs$lang$ctorStr等类似的工具。

我提出的补丁实施ExceptionInfo作为真实的deftype,并进行了一些修正以提供向后兼容性。我非常确信我们不应该破坏ExceptionInfo构造函数接受3个参数并在构造函数中动态合成其他字段当前的合同。

实现细节
1) 首先,我们像正常的deftype一样定义ExceptionInfo(以获取模板)
2) 然后在ExceptionInfoTypeTemplate中记住ExceptionInfo的引用
3) 然后用原始构造函数重新定义ExceptionInfo,该函数应模拟原始行为(通过刮取新创建的js/Error实例,但调用ExceptionInfoTypeTemplate以进行正确的deftype初始化)
4) 然后将ExceptionInfoTypeTemplate的键复制到ExceptionInfo中
5) 然后将ExceptionInfo的原型设置为ExceptionInfoTypeTemplate的原型
6) 然后将ExceptionInfo原型的构造函数指向我们的重新定义的构造函数
7) 然后修补ExceptionInfo的原型以继承js/Error(请注意这会覆盖ExceptionInfoTypeTemplate - 但我们不关心它)

这实际上为我们提供了一个良好工作的ExceptionInfo deftype,其中包含重新定义的构造函数,该构造函数包装了类型构造函数以实现向后兼容性。
我们还修补了ExceptionInfo的原型以继承js/Error,方式和原始代码一样。

注意:具有有效deftype,我们可以将IPrintWithWriter和toString实现移动到deftype本身。

(链接:1)https://github.com/binaryage/cljs-devtools/issues/23
(链接:2)https://github.com/binaryage/cljs-devtools/releases/tag/v0.8.0

8 个答案

0

评论者:thheller

为什么不在每个set!操作中都添加缺少的{{getBasis}}、{{cljs$lang$type}}、{{cljs$lang$ctorStr}}部件呢?

补丁看起来可能会弄乱高级编译,但这只是直觉,没有经过验证,你呢?

0

评论者:darwin

我运行了ClojureScript测试,我假定它们在与高级模式构建一起运行。在开发期间,当我的测试失败时,我看到了有关最小化名称的错误信息。

这看似是一种聪明的解决方案,但在我看来,原始代码也是一项工程。我的修复将随着deftype实现的未来更改而保持最新。我可以想象,当触及deftype时,人们可能会忘记更新这部分。

顺便说一下,还有一个与deftype和defrecord之间的不一致相关的补丁即将到来。如果defrecord与deftype共享通用实现,这种情况就可以避免了。

0

评论者:thheller

Closure通常对诸如重新定义之类的操作非常严格,但我想我的直觉是错的,测试应该包含高级模式。

我的问题是{{deftype}}是为了定义Clojure特定类型,ExceptionInfo不是,因为它继承自Error,就像在Clojure中不能有超类一样,在CLJS中也不能。所以如果我们将来改变{{deftype}},我们可能会以一种意外的方式破坏一些事情,只是一些东西只是重新使用了{{deftype}},但实际上并不是{{deftype}}。

是的,你必须做一些家务,但在处理继承时你不能强制执行{{deftype}}的规则。

仅代表我的两便士,像你建议的那样重新使用{{deftype}}也有好处。

0

评论者:darwin

不幸的是,我无法查找任何评论或文档解释为什么我们要在js/Error继承中这么做。

我要“修复”ExceptionInfo的第一尝试是将它简单地实现为一个普通的deftype。这工作得很好(对我的测试)。然后我试图在上面重新实现原始行为,以使其完全兼容。

0
by

评论者:darwin

仅添加一张激励性的截图

https://box.binaryage.com/CLJS-1722-example.png

这些黄色警告列出了由gobject/extend调用复制的属性。
展开的日志项目是新通过v0.8.0的cljs-devtools实现记录的。
最后的日志项目是旧通过v0.8.0的cljs-devtools实现记录的(cljs-devtools不识别ExceptionInfo为CLJS类型,但检测IPrintWithWriter并使用它来展示值)

0
by

评论者:mfikes

添加了CLJS-1722.patch到补丁池(i)

0
by

评论者:mfikes

CLJS-1722.patch通过CI和Canary(/)

0
by
参考资料:[https://clojure.atlassian.net/browse/CLJS-1722](https://clojure.atlassian.net/browse/CLJS-1722)(由darwin报告)
...