I want to add metadata to a byte array in Clojure. Since this is not allowed, one option I want to try is the simplest object wrapper that could work.
Here is the source code for with-meta.
That made me start looking at Clojure.lang.IObj
. I haven't found what I want yet.
Here's how you can create a deftype
that supports metadata.
(import '(java.io Writer))
(deftype Box [value _meta]
clojure.lang.IObj
(meta [_] _meta)
(withMeta [_ m] (Box. value m))
clojure.lang.IDeref
(deref [_] value)
Object
(toString [this]
(str (.getName (class this))
": "
(pr-str value))))
(defmethod print-method Box [o, ^Writer w]
(.write w "#<")
(.write w (.getName (class o)))
(.write w ": ")
(.write w (-> o deref pr-str))
(.write w ">"))
(defn box
([value] (box value nil))
([value meta] (Box. value meta)))
And here's some example usage:
user> (def boxed (box (->> (range 5)
(map byte)
(byte-array))
{:stuff :foo}))
#<Var@1acd39b: #<Box@c50aa1: #>>
user> @boxed
[0, 1, 2, 3, 4]
user> (meta boxed)
{:stuff :foo}
user> (meta (with-meta boxed {:stuff :bar}))
{:stuff :bar}
This is the simplest way I can think of to put metadata on a byte array (reify
doesn't work with clojure.lang.IObj
and records include more unrelated functionality).
Another option (and perhaps simpler depending on the context) would be to store the byte array in a map, with the metadata either right alongside it or as actual metadata.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With