首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >包装器-宏策略在Clojure中超过扩展类型失败

包装器-宏策略在Clojure中超过扩展类型失败
EN

Stack Overflow用户
提问于 2016-10-01 16:40:25
回答 1查看 79关注 0票数 0

我已经把我的更大的问题减少到一个人工的MVE (最小可行的例子)使用文件-io作为说明。我的问题涉及我在下面解释的某个包装器宏;它不涉及使用file-io API的更好方法;我只是使用file-io在一个小而简单的上下文中说明宏问题。我的实际问题中的包装宏策略很难展示和解释,但是这个MVE抓住了问题的要点。

考虑以下议定书:

代码语言:javascript
复制
(defprotocol Dumper
  (dump [this]))

以及在java.io.File上的实现

代码语言:javascript
复制
(extend-type java.io.File
  Dumper
  (dump [file]
    (with-open [rdr (io/reader file)]
      (doseq [line (line-seq rdr)]
        (println line)))))

我们已经做了一个(:use [clojure.java.io :as io])来获得reader函数。我可以如下所用:

代码语言:javascript
复制
(defn -main
  [& args]
  (dump (io/file "resources/a_file.txt")))

文本文件中的“你好”。

现在,我想创建协议的另一个实现,这次是通过java.lang.String。此实现封装字符串,将其视为文件路径字符串;创建clojure.java.io/file;然后调用协议的其他实现:

代码语言:javascript
复制
(extend-type java.lang.String
  Dumper
  (dump [path-str] (-> path-str, io/file, dump)))

就这样叫它:

代码语言:javascript
复制
(defn -main
  [& args]
  (dump (io/file "resources/a_file.txt"))
  (dump          "resources/a_file.txt"))

文本文件中的“你好”。文本文件中的“你好”。

在我的实际问题中,我在协议中有许多功能,其中一个实现只是以所示的方式包装另一个。注意,在包装器实现中,方法名dump被复制。让我们用宏消除该复制(当真正的协议有许多方法时,值得这样做):

代码语言:javascript
复制
(defmacro wrap-path-string [method]
  `(~method [path-str] (-> path-str, io/file, ~method)))

(extend-type java.lang.String
  Dumper
  (wrap-path-string dump))

噢,编译器不喜欢它:

此类型不支持线程"main“中的异常:符号,编译:(wrapper_mve/core.clj:18:1)在clojure.lang.Compiler.analyze(Compiler.java:6688) at clojure.lang.Compiler.analyze(Compiler.java:6625) at clojure.lang.Compiler$MapExpr.parse(Compiler.java:3072)

我试过macroexpand-all'ing‘和macroexpand-1’处理宏调用(在苹果酒中很难在这里复制),它看起来不错。我不知道如何进行更深入的调试,但也许这里的人能发现问题所在。

同样,我知道这个MVE有更好的解决方案,使用文件-io API,但我真的想调试宏,而不是想办法避免使用它,因为我需要包装-宏策略在我的实际问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-10-01 18:25:27

我认为问题在于,extend-type本身就是一个宏,宏扩展从最外层的形式开始(而不是函数计算,它在调用函数之前对每个参数进行评估)。在这种情况下,extend-type的宏展开试图将表单(wrap-path-string dump)看作函数体,并期望第二个条目是arg向量,但找到符号dump

如果您想要走这条路,我认为您需要编写一个宏,该宏将生成所需的expand-type表单,并且所有函数体都已经展开。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39809055

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档