2017-03-21 45 views
1

漂亮的印刷本地圖出來很醜陋:自定義地圖的印刷:類型Clojure中

{: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 "[email protected]"]}, 
    :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 "[email protected]"], 
    :do-hypothetically 
    #object[fargish.workspace$do_hypothetical_boost 0x68d6475a "[email protected]"]} 

大多數時候,我並不需要看到的大部分是。我想它看起來大致是這樣的:

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

是否Clojure中提供了一個鉤子,讓我插入代碼,這樣,如果一個地圖的:type鍵的值是:movestr將調用一個函數我寫的生成字符串?

我查看過print-method。如果我正確地理解了這一點,那將擴展一種派生於論證類型的多方法,即, clojure.lang.PersistentArrayMap,而不是地圖的:type。 AFAIK,沒有辦法「轉發」到先前定義的多方法,否則我可以爲看到:type的clojure.lang.PersistentArrayMap編寫print-method,然後在其值不是:move時調用通用方法。

即使只是自定義pprint會有所幫助。理論上,pprint是非常可定製的,但我還沒有找到解釋如何解決的documentationThis不完整,並暗示pprint不是真的完成。

影響pprint的輸出會很好,但並非嚴格必要。只要能夠影響strprint將是一個很大的幫助。

回答

2

print-methodalready looks at對你對象的:type關鍵。只需將:type安排在元數據中,而不是(或者除了)實際的地圖本身,並且您可以定義自己的打印方法。

+0

這是否適用於漂亮的打印? –

+0

恐怕你自己用pprint。它的使用幾乎不像核心打印設備那麼多,我相信因爲這個原因,它不那麼靈活:更少的人關心擴展它。我認爲你可以做的最好的是:定義一種新的pprint調度方法來代替簡單調度,在你的調度中實現你想要的任何自定義的東西,然後將其他決策委託給簡單調度。但它並不像打印方法那麼簡單,因爲它默認不考慮元數據。 – amalloy

+0

然後你應該寫這個答案。 OP明確詢問了pprint。 –

1

有一個名爲zprint的漂亮打印包,您可以使用它,它可以讓你非常接近你想要的東西,並且當你的輸出很大並且難以在視覺上理解時仍然可以獲得漂亮打印的好處。我給下面的一些例子:

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

user=> (zprint soq) 
{:do #<[email protected] clojure.lang.PersistentList/Primordial>, 
:do-hypothetically #<[email protected] clojure.lang.PersistentList/Primordial>, 
:from {:dockclass :input, 
     :name :left-operand, 
     :nodeid :plus, 
     :ref [:plus :left-operand], 
     :value {:args [:result :right-operand], 
       :f #<[email protected] 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 #<[email protected] clojure.lang.PersistentList/Primordial>}}, 
:to {:name :output, 
     :dockclass :output, 
     :nodeid :source11, 
     :ref [:source11 :output], 
     :value 11}, 
:do #<[email protected] clojure.lang.PersistentList/Primordial>, 
:do-hypothetically #<[email protected] 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漂亮的打印開始了,它更容易閱讀和理解。