通过以下方式自定义地图打印:输入Clojure

时间:2017-03-21 16:47:14

标签: clojure string-formatting pretty-print

漂亮地打印这张地图非常难看:

  {:type :move,
   :name :boost,
   :from
   {:nodeid :plus,
    :name :left-operand,
    :value
    {:args [:result :right-operand],
     :f
     #object[fargish.workspace_test$fn__159675$fn__159678 0xb3f518f "fargish.workspace_test$fn__159675$fn__159678@b3f518f"]},
    :dockclass :input,
    :ref [:plus :left-operand]},
   :to
   {:nodeid :source11,
    :name :output,
    :value 11,
    :dockclass :output,
    :ref [:source11 :output]},
   :do
   #object[fargish.workspace$do_boost 0x179d226e "fargish.workspace$do_boost@179d226e"],
   :do-hypothetically
   #object[fargish.workspace$do_hypothetical_boost 0x68d6475a "fargish.workspace$do_hypothetical_boost@68d6475a"]}

大多数时候,我不需要看到大部分内容。我希望看起来大致像这样:

#boost{:from [:plus :left-operand] :to [:source11 :output]}

Clojure是否提供了一个钩子让我插入代码,以便如果地图的:type键的值为:movestr将调用我写的函数生成字符串?

我调查了print-method。如果我理解正确,那将扩展一个多方法,该方法调度参数的类型,即。 clojure.lang.PersistentArrayMap,而不是地图的:type。 AFAIK,没有办法#34;前进"以前定义的多方法,或者我可以为查看print-method的clojure.lang.PersistentArrayMap写一个:type,然后调用泛型方法,如果它的值不是:move

即使只是自定义pprint也会有所帮助。从理论上讲,pprint可以自定义,但我还没有找到documentation来解释如何。 This不完整,表明pprint并未真正完成。

影响pprint的输出会很不错,但并不是必须的。能够影响strprint会有很大的帮助。

2 个答案:

答案 0 :(得分:2)

print-method already looks at您对象的元数据上的:type键。只需安排:type在元数据中而不是(或除了)实际地图本身,您就可以定义自己的打印方法。

答案 1 :(得分:2)

有一个名为zprint的漂亮打印软件包可供您使用,它可以让您非常接近您想要的东西,并且当您的输出很大且难以在视觉上理解时,仍然可以获得漂亮打印的好处。我在下面给出了一些例子:

; Basic zprint pretty-print of a similar map.  Note that it orders the keys
; alphabetically

user=> (zprint soq)
{:do #<Fn@4d0e1990 clojure.lang.PersistentList/Primordial>,
 :do-hypothetically #<Fn@4d0e1990 clojure.lang.PersistentList/Primordial>,
 :from {:dockclass :input,
        :name :left-operand,
        :nodeid :plus,
        :ref [:plus :left-operand],
        :value {:args [:result :right-operand],
                :f #<Fn@4d0e1990 clojure.lang.PersistentList/Primordial>}},
 :name :boost,
 :to {:dockclass :output,
      :name :output,
      :nodeid :source11,
      :ref [:source11 :output],
      :value 11},
 :type :move}

; You can order the keys so the ones you care about come in the order
; you want.

user=> (zprint soq {:map {:key-order [:name :from :to]}})
{:name :boost,
 :from {:name :left-operand,
        :dockclass :input,
        :nodeid :plus,
        :ref [:plus :left-operand],
        :value {:args [:result :right-operand],
                :f #<Fn@4d0e1990 clojure.lang.PersistentList/Primordial>}},
 :to {:name :output,
      :dockclass :output,
      :nodeid :source11,
      :ref [:source11 :output],
      :value 11},
 :do #<Fn@4d0e1990 clojure.lang.PersistentList/Primordial>,
 :do-hypothetically #<Fn@4d0e1990 clojure.lang.PersistentList/Primordial>,
 :type :move}

; You can get zprint to ignore keys completely

user=> (zprint soq {:map {:key-order [:name :from :to] :key-ignore-silent [[:from :name] :dockclass :nodeid :value :do :do-hypothetically :type [:to :name]]}})
{:name :boost,
 :from {:ref [:plus :left-operand]},
 :to {:ref [:source11 :output]}}

; You can configure zprint to do this all the time

user=> (zprint.core/set-options! {:map {:key-order [:name :from :to] :key-ignore-silent [[:from :name] :dockclass :nodeid :value :do :do-hypothetically :type [:to :name]]}})

; Now you just zprint it...

user=> (zprint soq)
{:name :boost,
 :from {:ref [:plus :left-operand]},
 :to {:ref [:source11 :output]}}

您可以使用~/.zprintrc文件配置zprint,以便始终执行此操作。

您还可以使用czprint将其着色,您也可以使用:键颜色贴图以任何方式为按键着色。当我查看整个地图序列时,我觉得这很有用 - 改变一个键的颜色并按照我想要的方式排序键让我更容易理解一系列地图。

构建一个查看:type然后调用zprint的函数会很简单 适用于该类型的任何选项。当然,:ref仍然在那里,但是当你有大量输出时,权衡就会出现,并且zprint非常适合打印并且更容易阅读和理解。