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

欢迎!请参阅关于页面了解该平台的工作原理更多信息。

0
ClojureScript

目前ExceptionInfo以原生构造函数的形式实现,从js/Error继承了部分专用的javascript级补丁,以满足deftype功能的一小部分需求(主要是用于打印)。

不幸的是,这与cljs-devtools(链接:1)不太兼容。当我和ExceptionInfo以及支持打印deftype的新功能v0.8的cljs-devtools(链接: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 - 但我们对此不感兴趣)

这实际上使我们得到了一个具有重定构造函数的deftype来有效地工作,该构造函数会包装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
by

评论者:darwin

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

这似乎是一个黑客式解决方案,但我认为原始代码也很可能是黑客式的。我的黑客式方法将与deftype实施的未来更改保持同步。我可以想象,当触及deftype时,人们会忘记更新这一部分。

顺便说说。还有一个与deftype和defrecord之间差异相关的补丁要推出。如果defrecord与deftype共享共同实现,这种情况就可以避免。

0
by

评论者:thheller

Closure通常对重新定义内容非常严格,但我猜我的直觉是错的,测试应该涵盖高级模式。

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

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

只是我的两分钱,再次使用{{deftype}}也有优势(正如你所建议的)。

0
by

评论者:darwin

不幸的是,我无法查找任何评论或文档解释我们在那里做js/Error继承的理由。

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

0
by

评论者: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
参考:[https://clojure.atlassian.net/browse/CLJS-1722](https://clojure.atlassian.net/browse/CLJS-1722)(由darwin报告)
...