2024 Clojure状态调查中分享您的想法!

欢迎!有关如何使用本站,请参阅关于页面了解更多信息。

0
ClojureScript

目前ExceptionInfo作为原始构造函数实现,继承了js/Error,并使用一些定制的JavaScript修复来解决deftype功能的一小部分(主要是打印)。

不幸的是,这并不与cljs-devtools(link: 1)很好地配合。当我在ExceptionInfo和cljs-devtools v0.8(新支持打印deftype, link: 2)中进行实验时,这个问题出现了。ExceptionInfo不包含getBasis, cljs$lang$type, cljs$lang$ctorStr和类似的机制。

我提出的修复方案是实施ExceptionInfo作为适当的deftype,并提供一些修补工作以实现向后兼容性。我坚信我们不应该破坏ExceptionInfo构造函数接受3个参数并动态合成其他字段当前协议。

实现细节
1) 首先,我们定义ExceptionInfo作为一个正常的deftype(以获得模板)
2) 然后,我们在ExceptionInfoTypeTemplate中记住对ExceptionInfo的引用
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

评论者:thheller

为什么不在每次set!时直接添加缺失的{{getBasis}}、{{cljs$lang$type}}、{{cljs$lang$ctorStr}}片段呢?

看起来这个补丁可能会搞砸高级编译,但这只是直觉,不是经过验证的,是你吗?

0

由darwin发表评论:

我运行了clojurescript测试,并假设它们也对高级模式构建进行运行。在开发期间,当我的测试失败时,我看到有关minified names的错误消息。

这可能看起来像一个黑客解决方案,但在我看来,原始代码也是。我的黑客解决方案将随着deftype实现的未来变化而保持更新。我可以想象,当接触到deftype时,人们会忘记更新这部分。

顺便说一下,还有一个与此相关的补丁,涉及deftype和defrecord之间的差异。如果defrecord与deftype共享通用实现,这可能已经可以避免。

0

评论者:thheller

闭包通常对重新定义的东西非常严格,但我猜我的直觉是错误的,测试应该覆盖高级模式。

我这个问题是,{{deftype}}是用于定义Clojure特定类型。ExceptionInfo不是,因为它继承自Error,就像在Clojure中没有超类一样,在CLJS中也不能。所以,如果我们未来要更改{{deftype}},我们可能会以一种意想不到的方式打破东西,只是重新使用了{{deftype}},但实际上并不是{{deftype}}。

是的,你需要做一些清理工作,但在处理继承时,你不能强制执行{{deftype}}的规则。

仅代表个人观点,重新使用{{deftype}}也有优势(正如你所建议的)。

0

由darwin发表评论:

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

我第一次尝试“修复”ExceptionInfo只是简单地将其作为普通deftype实现。这对我来说很正常(对于我的测试)。然后我尝试在上面的原始行为之上重新实现,只是为了使其100%兼容。

0

由darwin发表评论:

添加一个激励性的截图

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

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

0

评论由: mfikes 发布

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

0

评论由: mfikes 发布

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

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