Son*_*oth 5 graph clojure cyclic charsequence pprint
我有一个使用dosync和创建的循环图ref-set.当我传递给println我时,我得到了一个java.lang.StackOverflowError我所期望的,因为它有效地试图打印一个无限嵌套的结构.
我发现,如果我这样做(str my-ref)会产生看起来像vertex@23f7d873并且实际上并不试图遍历结构并将所有东西都打印出来的东西,所以这就解决了这个问题,但是只有在我非常小心我的情况时才会有所帮助. m打印到屏幕上.我希望能够打电话给(println my-graph)它打印ref作为某种类型的自定义文本(可能涉及str),以及其他非ref的东西通常.
目前我有一个自定义打印功能,可以自己打印结构的每个元素,并完全跳过打印ref.(事实证明,看着vertex@23f7d873实际上并不是非常有用).使用起来很尴尬,阻碍了在REPL中对东西进行随意检查,同时也阻止了Emacs检查员在swank.core/break调试时查看内容.
一个细节ref实际上是一个值,defstruct其中还包含一些我试图正常打印的其他东西.
所以我想知道我应该走哪条路.我看到这些选项:
extend-type并将CharSequence协议应用于我的defstructed结构,以便在遇到ref它时可以正常工作.这仍然需要对结构进行逐个字段检查,并且需要特殊情况ref,但至少它将问题本地化为结构而不是包含结构的任何内容.CharSequence在遇到协议时覆盖协议ref.这允许更加本地化的行为,并允许我在REPL处查看循环引用,即使它不在结构体内.这是我的首选.toString我认为在某种程度上被称为某种程度的事情println.我对这个选项最无知.对其他人一无所知,但我一直在读书Joy of Clojure,现在我受到了启发.同样,此解决方案应该适用于print和pprint尝试打印循环引用时通常会禁用的任何其他内容.我应该采用什么策略?
非常感谢任何输入.
您想要做的是创建一个新的命名空间并定义您自己的打印函数,该函数模拟 clojure 打印对象的方式,并默认为 clojure 的方法。
详细地:
作为奖励,如果您使用的是 clojure 1.4.0,则可以使用标记文字,以便也可以读取输出。您需要重写*data-readers*自定义标签的映射和返回 ref 对象的函数。您还需要重写读取字符串行为以确保调用绑定*data-readers*。
我提供了 java.io.File 的示例
(ns my.print
(:refer-clojure :exclude [pr-str read-string print-method]))
(defmulti print-method (fn [x writer]
(class x)))
(defmethod print-method :default [o ^java.io.Writer w]
(clojure.core/print-method o w))
(defmethod print-method java.io.File [o ^java.io.Writer w]
(.write w "#myprint/file \"")
(.write w (str o))
(.write w "\""))
(defn pr-str [obj]
(let [s (java.io.StringWriter.)]
(print-method obj s)
(str s)))
(defonce reader-map
(ref {'myprint/file (fn [arg]
(java.io.File. arg))}))
(defmacro defdata-reader [sym args & body]
`(dosync
(alter reader-map assoc '~sym (fn ~args ~@body))))
(defn read-string [s]
(binding [*data-readers* @reader-map]
(clojure.core/read-string s)))
Run Code Online (Sandbox Code Playgroud)
现在你可以像这样打电话(println (my.print/pr-str circular-data-structure))
| 归档时间: |
|
| 查看次数: |
940 次 |
| 最近记录: |