Fork me on GitHub
#unrepl
<
2017-04-04
>
thheller11:04:27

@cgrand any reason why you used (System/identityHashCode x) and not (hash x) in https://github.com/cgrand/unrepl/blob/master/src/unrepl/print.clj#L103

thheller11:04:35

ah nvm .. its for Object

cgrand11:04:49

Yes I wanted identity and a bad hash may never return

cgrand11:04:45

So I changed my mind on how to plug log libs in: unrepl exposes two functions and the client (repl frontend not user) has to create an appender on top of that

thheller11:04:46

I started writing the custom object printer that would be equivalent to the thing that makes the js/console work

cgrand11:04:22

@thheller what’s missing?

thheller11:04:03

nothing really, just exploring a different approach

thheller11:04:02

I hate *print-length* .. that is pretty much it

thheller11:04:49

but what I want expects a rich GUI, so the output is not strictly human-readable edn-ish

thheller11:04:02

ie. printing {:foo ["hello" 1 'two (list 1 2 3) #{1 2 3}]} produces

thheller11:04:16

[:collection
 {:type :map}
 [:entry
  {}
  [:named {:type :keyword} nil "foo"]
  [:ref
   {:id -994784545}
   [:span {:type :list} "clojure.lang.PersistentVector [count: 5]"]]]]

thheller11:04:42

so its hiccup-like markup

thheller11:04:25

you can then use the :ref id to get the "body" of the ref -994784545

thheller11:04:35

which would be

thheller11:04:37

[:collection
 {:type :vector}
 [:entry {} [:number 0] [:string "hello"]]
 [:entry {} [:number 1] [:number 1]]
 [:entry {} [:number 2] [:named {:type :symbol} nil "two"]]
 [:entry
  {}
  [:number 3]
  [:ref
   {:id 736442005}
   [:span {:type :list} "clojure.lang.PersistentList [count: 3]"]]]
 [:entry
  {}
  [:number 4]
  [:ref
   {:id 439094965}
   [:span {:type :list} "clojure.lang.PersistentHashSet [count: 3]"]]]]

thheller11:04:09

so it always only prints one value and leaves references for you to get later

thheller11:04:52

[:collection props entry-1 entry-2 ...]

thheller11:04:05

[:entry props key value]

thheller11:04:31

keywords, symbols are [:named props namespace name]

thheller11:04:09

it is basically what the js/console custom formatters do

cgrand11:04:41

A link to these custom formatters?

cgrand11:04:59

meanwhile in a repl:

user=> (unrepl.repl/start)
[:unrepl/hello {:session :session474, :actions {:exit (unrepl.repl/exit! :session474), :log-eval (clojure.core/some-> :session474 unrepl.repl/session :log-eval), :log-all (clojure.core/some-> :session474 unrepl.repl/session :log-all), :set-source (unrepl.repl/set-file-line-col :session474 <#C4C63FWP5|unrepl>/param :unrepl/sourcename <#C4C63FWP5|unrepl>/param :unrepl/line <#C4C63FWP5|unrepl>/param :unrepl/column)}}]
[:prompt {:file "unrepl-session", :line 1, clojure.core/*ns* <#C4C63FWP5|unrepl>/ns user, clojure.core/*warn-on-reflection* false}]
[:prompt {:file "unrepl-session", :line 2, clojure.core/*ns* <#C4C63FWP5|unrepl>/ns user, clojure.core/*warn-on-reflection* false}]
(def log (let [w (clojure.core/some-> :session474 unrepl.repl/session :log-eval)] (fn [& args] (into [:trace (-> *ns* ns-name name) (java.util.Date.)] args))))
[:echo {:from [2 1], :to [3 1]} 1]
[:started-eval {:actions {:interrupt (unrepl.repl/interrupt! :session474 1), :background (unrepl.repl/background! :session474 1)}} 1]
[:eval <#C4C63FWP5|unrepl>/object [#unrepl.java/class clojure.lang.Var "0x27b6fd39" {:unrepl.ref/status :ready, :unrepl.ref/val <#C4C63FWP5|unrepl>/object [#unrepl.java/class user$fn__477$fn__479 "0x628a2e2d" "user$fn__477$fn__479@628a2e2d"]}] 1]
[:prompt {:file "unrepl-session", :line 3, clojure.core/*ns* <#C4C63FWP5|unrepl>/ns user, clojure.core/*warn-on-reflection* false}]
So we defined user/log and we are going to use it:
(log "hello" :thheller {:foo 42} (range))
[:echo {:from [4 1], :to [5 1]} 3]
[:started-eval {:actions {:interrupt (unrepl.repl/interrupt! :session474 3), :background (unrepl.repl/background! :session474 3)}} 3]
[:eval [:trace "user" <#C4C63FWP5|unrepl>/object [#unrepl.java/class java.util.Date "0x7ae3e597" "Tue Apr 04 13:44:08 CEST 2017"] "hello" :thheller {:foo 42} (0 1 2 3 4 5 6 7 8 9 <#C4C63FWP5|unrepl>/... {:get (unrepl.repl/fetch :G__486)})] 3]
[:prompt {:file "unrepl-session", :line 5, clojure.core/*ns* <#C4C63FWP5|unrepl>/ns user, clojure.core/*warn-on-reflection* false}]

cgrand11:04:47

hmm oops a bug

thheller11:04:02

so the custom formatters have the concept of a header and a body

thheller11:04:12

header is basically the "short" version

thheller11:04:40

[:span {:type :list} "clojure.lang.PersistentList [count: 3]"]

thheller11:04:42

this is the header

thheller11:04:01

ooops should not be :span 😉

thheller11:04:39

but the body is the [:collection ...]

cgrand11:04:05

ok, without forgetting the call to the logger:

(def log (let [w (clojure.core/some-> :session474 unrepl.repl/session :log-eval)] (fn [& args] (w (into [:trace (-> *ns* ns-name name) (java.util.Date.)] args)))))
[:echo {:from [5 1], :to [6 1]} 4]
[:started-eval {:actions {:interrupt (unrepl.repl/interrupt! :session474 4), :background (unrepl.repl/background! :session474 4)}} 4]
[:eval <#C4C63FWP5|unrepl>/object [#unrepl.java/class clojure.lang.Var "0x27b6fd39" {:unrepl.ref/status :ready, :unrepl.ref/val <#C4C63FWP5|unrepl>/object [#unrepl.java/class user$fn__487$fn__489 "0x7b3d57bf" "user$fn__487$fn__489@7b3d57bf"]}] 4]
[:prompt {:file "unrepl-session", :line 6, clojure.core/*ns* <#C4C63FWP5|unrepl>/ns user, clojure.core/*warn-on-reflection* false}]
user/log ise defined
(log "hello" :thheller {:foo 42} (range))
[:echo {:from [6 1], :to [7 1]} 5]
[:started-eval {:actions {:interrupt (unrepl.repl/interrupt! :session474 5), :background (unrepl.repl/background! :session474 5)}} 5]
[:log [:trace "user" <#C4C63FWP5|unrepl>/object [#unrepl.java/class java.util.Date "0x1f892f92" "Tue Apr 04 13:48:42 CEST 2017"] "hello" :thheller {:foo 42} (0 1 2 3 4 5 6 7 8 9 <#C4C63FWP5|unrepl>/... {:get (unrepl.repl/fetch :G__494)})] 5]
[:eval nil 5]

cgrand11:04:52

thanks for the link

thheller11:04:59

the problem I have with the normal print is that it still can get too long

thheller11:04:11

even with *print-length* 10 or so

thheller11:04:25

case in point: the cljs.anaylzer AST 😛

cgrand11:04:38

set everything to 1 (length & depth)

cgrand11:04:10

it’s not because you get too much that you have to display it

thheller11:04:22

hmm yeah dunno .. your print is probably better since it is still somewhat readable without a tool

cgrand15:04:23

I documented how to hook up unrepl browseable log to timbre: https://github.com/cgrand/unrepl#log-eval-and-log-all

dominicm23:04:36

Finally think I get this repl vs tooling thing now. So it would be acceptable to have a mimic/similar protocol that was used for other needs.