@djblue IntelliJ 2024.1 dropped so plugin needs an update π
Deployed https://github.com/djblue/portal/actions/runs/8566232685, now IntelliJ just needs to approve it
PR is up for you, Chris.
Will get this merged and released soon, thanks for the PR!
Iβm experiencing a strange issue with portal. I tapped a data structure that has nested record-like objects. I then updated it recursively replacing record-like objects with plain clojure maps and tapped into portal. For some reason, it was still showing the record names on top of the objects even though I later figured that those were plain maps. Was there some sort of data indexing that might have gotten confused?
Good point, sounds like metadata is also going to be ignored when comparing nested objects, and also not shown correctly. I just verified it with this example (see the screenshot). So it looks like it is not very niche. See
(= (#'portal.runtime/value->key {:a (with-meta [1] {:one 1})})
(#'portal.runtime/value->key {:a (with-meta [1] {:two 2})}))
true
(tap> {:a (with-meta [1] {:one 1})})
true
(tap> {:a (with-meta [1] {:two 2})})
trueI was able to reproduce this with basic clojure types. See the issue I filed: https://github.com/djblue/portal/issues/218.
Thanks for narrowing down this issue π So when Portal captures a value, it does take into consideration the metadata and type https://github.com/djblue/portal/blob/master/src/portal/runtime.cljc#L127-L131. However, I think the issue here is the parent map is also captured, which in a sense allows for bypassing the child check this check π€
So more specifically, this is the issue:
(= (value->key [1]) (value->key '(1))) ; => false, which is good
(= (value->key {:a [1]}) (value->key {:a '(1)})) ; => true, which is badNot sure how to solve this issue without Portal having its own notion of equality π€
Could it be using hashcode maybe or clojure equality?
I confirmed that if I first tap the plain maps object and then its original record-like, then nested structures of both will be shown as plain maps. If I do the opposite, tap record-like structure first and then plain map one - then nested structures for both are shown as record-like structures.
But if I do prn on each, I get clear picture that one object is made of plain maps and another from record-like structures.
Also if I select each and then do (-> user/p portal.api/selected prn) , I get the same value printed even though when I printed tap-list, it contained two different objects.
Interestingly, if I select both, printing them will show two different objects.
When I say record-like structure I refer to a Java object that implements some Clojure APIs, so it may be seen both as a map and as a record.
It implements
IObj,
IMapIterable,
IKVReduce,
IRecord,
Map<K, V>,
IPersistentMap,
MapEquivalence,
IHashEq,
IFn,
IMapIterable,
IKVReduce,
IObj
and extends AFn.This behavior is only happening to objects that are stored in vectors. I. e. in {:v [{:a 1}]} , {:a 1} gets affected. While in {:p {:a 1}}, the same {:a 1} doesnβt get affected.
It takes a little while to come up with a test case here, but Iβll keep trying. Just maybe not as fast as I expected.
Nice, as I mentioned in the issue, my original case is still borken. Iβm trying to come up with a test case. What Iβm currently struggling with is to create an object that displays a type in the portal UI. What determines when a type is shown? For example, when I create the following object, its type is not shown in portal:
(def x (proxy [clojure.lang.APersistentMap clojure.lang.IRecord clojure.lang.IObj]
[]
(toString [] "MyMap")
(seq [] (clojure.lang.IteratorSeq/create (.iterator base)))
(without [_] this)
(meta [] {})
(withMeta [_] this)
(assoc [_ _] this)
(assocEx [_ _] this)
(iterator [] (.iterator base))
(containsKey [_] false)
(entryAt [_] nil)
(count [] 1)
(empty [] this)
(valAt ([_] nil)
([_ _] nil))))
even though the type is something like user.proxy$clojure.lang.APersistentMap$IRecord$efc9b825Currently only records show their type via https://github.com/djblue/portal/blob/master/src/portal/runtime.cljc#L262-L263
If the metadata include this key :portal.runtime/type , it will render it as the type
Thanks, this helps!
Ok, I think https://github.com/djblue/portal/commit/94171f4b9c1b2712871a19078288f793fa3fb17d fixes the issue π