Adding meta data to string?

864 views
Skip to first unread message

Jung Ko

unread,
Oct 3, 2009, 3:17:59 AM10/3/09
to clo...@googlegroups.com
Is it possible to add meta-data to Strings?

(with-meta "Hello" {:key 123})

java.lang.String cannot be cast to clojure.lang.IObj
[Thrown class java.lang.ClassCastException]

One solution that I found by Googling around is to extend the Java
class that I want to add meta data (String in this case) and have the
new class implement IObj. However, that solution requires me to
program in Java and seems like an overkill for the String class.

Is there a better & easier way to add meta-data to strings?

Sincerely,
Jung Ko

pmf

unread,
Oct 3, 2009, 10:23:49 AM10/3/09
to Clojure
On Oct 3, 9:17 am, Jung Ko <koj...@gmail.com> wrote:
> Is it possible to add meta-data to Strings?
>
> (with-meta "Hello" {:key 123})
>
> java.lang.String cannot be cast to clojure.lang.IObj
>   [Thrown class java.lang.ClassCastException]

And String is final, making deriving from it impossible.

One way (most probably not the best way) would be to wrap it in a Var
and attach the metadata to the Var, i.e.

(def #^{:blah :foo} my-string "some string")

Note that to access the metadata of the Var later, you have to use var-
quote:

^#'my-string

Jung Ko

unread,
Oct 5, 2009, 12:43:20 PM10/5/09
to clo...@googlegroups.com
On Sat, Oct 3, 2009 at 7:23 AM, pmf <phil....@gmx.de> wrote:
>
> And String is final, making deriving from it impossible.
>
> One way (most probably not the best way) would be to wrap it in a Var
> and attach the metadata to the Var, i.e.
>
> (def #^{:blah :foo} my-string "some string")
>
> Note that to access the metadata of the Var later, you have to use var-
> quote:
>
> ^#'my-string
>

Thanks for the suggestion. Looks like there is no elegant way to add
meta data to strings. I ended up changing my functions slightly so
that I don't need to embed the meta data in the string.

Thanks,
Jung

Travis

unread,
Oct 6, 2009, 12:07:21 AM10/6/09
to Clojure
I wonder if anyone has tried namespace level metadata hashes rather
than the current approach of putting it on the object itself. I would
do it this way:

tw$ repl
Clojure 1.1.0-alpha-SNAPSHOT
user=> (ns meta-experiment (:import java.util.WeakHashMap))
java.util.WeakHashMap
meta-experiment=> (def meta-var (WeakHashMap.))
#'meta-experiment/meta-var
meta-experiment=> (defn my-with-meta [the-obj the-meta] (do (if (.get
meta-var the-obj) (throw (Exception. "sorry, immutable"))) (.put meta-
var the-obj the-meta) the-obj))
#'meta-experiment/my-with-meta
meta-experiment=> (defn my-get-meta [the-obj] (.get meta-var the-obj))
#'meta-experiment/my-get-meta
meta-experiment=> (def test-obj (my-with-meta "I have meta" {:meta
"data"}))
#'meta-experiment/test-obj
meta-experiment=> ((my-get-meta test-obj) :meta)
"data"
meta-experiment=> (def should-not-work (my-with-meta "I have
meta" {:does-not "get stored"}))
java.lang.Exception: sorry, immutable (NO_SOURCE_FILE:7)


WeakHashMaps are designed for situations like this to avoid memory
leaks. When the object is garbage collected and the association is no
longer in the map, the metadata may be set once again.


On Oct 5, 9:43 am, Jung Ko <koj...@gmail.com> wrote:
Reply all
Reply to author
Forward
0 new messages