2024年Clojure调查!中分享您的想法。

欢迎!有关此如何工作的更多信息,请参阅关于页面。

0 投票
ClojureScript

目前ExceptionInfo作为原始构造函数实现,继承自js/Error并在JavaScript级别进行了一些即兴修补以满足deftype功能的很小一部分(主要是用于打印)。

这与cljs-devtools(link: 1)不兼容。在开始使用ExceptionInfo和最新支持打印deftype的cljs-devtools v0.8(link: 2)时出现了这个问题。ExceptionInfo不包含getBasis、cljs$lang$type、cljs$lang$ctorStr等类似机制。

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

实现细节
1) 首先,我们将ExceptionInfo定义为正常的deftype(以获得模板)
2) 然后,我们将ExceptionInfo在ExceptionInfoTypeTemplate中的引用保存在那里
3) 然后,我们使用原始构造函数重新定义ExceptionInfo,该构造函数应该模仿原始行为(通过抓取新创建的js/Error实例,但调用ExceptionInfoTypeTemplate来进行合适的deftype初始化)
4) 然后,我们将ExceptionInfoTypeTemplate中的键复制到ExceptionInfo中
5) 然后,我们将ExceptionInfo的原型设置为ExceptionInfoTypeTemplate的原型
6) 然后,我们将ExceptionInfo原型的构造函数指向我们重新定义的构造函数
7) 然后,我们将ExceptionInfo的原型修补以从js/Error继承(注意这也覆盖了ExceptionInfoTypeTemplate - 但我们不在乎这一点)

这有效地为我们提供了一个具有重新定义的构造函数的正确工作的ExceptionInfo deftype,该构造函数包装了deftype的构造函数以实现向后兼容。
我们还修补ExceptionInfo的原型以按与原始代码相同的方式从js/Error继承。

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

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

8 答案

0 投票
by

评论由:thheller 发布

为什么不在每个 set! 添加缺少的 {{getBasis}}、{{cljs$lang$type}} 和 {{cljs$lang$ctorStr}} 块呢?

这个补丁看起来可能会弄乱高级编译,但这只是一种直觉,并不是我经过验证的,你验证了吗?

0 投票
by

评论由:darwin 发布

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

这看起来可能是一种拙劣的解决方案,但在我个人看来,原始代码也是一种拙劣的做法。我的这种做法会随着 future 更新 deftype 实现而保持最新。我可以想象人们会在触及 deftype 时忘记更新这部分。

顺便说一下,还有一个与 deftype 和 defrecord 之间差异相关的补丁即将到来。如果 defrecord 与 deftype 共享公共实现,本来可以避免这种情况。

0 投票
by

评论由:thheller 发布

Closure 通常对重新定义内容很严格,但我猜我的直觉错了,测试应该包括高级。

我对这件事的看法是,{{deftype}} 用于定义 Clojure 特定类型。ExceptionInfo 不是,因为它从 Error 继承,就像在 Clojure 中不能有超类一样,在 CLJS 中也不能。所以我们 IF 未来改变了 {{deftype}},可能会以意想不到的方式打破某些事情,这些事情只是重新使用了 {{deftype}},但实际上不是 {{deftype}}。

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

这只是我的一点小看法,重复使用 {{deftype}} 也有优点(正如你建议的)。

0 投票
by

评论由:darwin 发布

不幸的是,我无法找到任何评论或文档解释为什么我们在那里进行 js/Error 继承。

我最初尝试“修复” ExceptionInfo 的方式是简单地将其作为普通 deftype 实现。这对我来说工作得很好(对于我的测试)。然后我尝试在顶部重新实现原始行为,以确保 100% 兼容。

0 投票

评论由:darwin 发布

添加一张富有启发性的截图

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

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

0 投票

评论者:mfikes

将CLJS-1722.patch添加到补丁揽(i)

0 投票

评论者:mfikes

CLJS-1722.patch通过CI和Canary

0 投票
...