I'm trying to contribute to an open-source application called stensil. It is written in Clojure.
stensil
is a templating engine that works on top of .docx. The templating engine declares a bunch of custom functions to be used in a template. A full list of functions is quite short and can be seen here.
What I need is to add another custom function that checks if a list contains an element. Following existing examples, I did this:
(defmethod call-fn "contains" [_ item items] (contains? items item))
To test this, I created a .docx file that contains the following snippet:
{%= contains(5, data) %}
and a .json file that contains this:
{
"data": [9, 4, 1, 6, 3]
}
Then I run the application like this:
java -jar stencil-core-0.3.8-standalone.jar template.docx sample.json
Unfortunately, when used, the function I defined doesn't work, throwing the following exception:
java.lang.IllegalArgumentException: contains? not supported on type: java.util.Collections$UnmodifiableRandomAccessList
It appears that items
is of type java.util.Collections$UnmodifiableRandomAccessList
. Indeed, if I add a (println items)
to the function I get this:
#object[java.util.Collections$UnmodifiableRandomAccessList 0x778ca8ef [9, 4, 1, 6, 3]]
I tried doing it differently by using some
function. This answer suggests it should work most of the time. Unfortunately both variants below return nil
:
(defmethod call-fn "contains" [_ item items] (some #{item} items))
(defmethod call-fn "contains" [_ item items] (some #(= item %) items))
I've never written a line of Clojure in my life before, and a bit lost now. What am I doing wrong? Would it make sense to convert the list from UnmodifiableRandomAccessList to something that some
or contains?
can work with? If yes, how do I perform such conversion on items
variable?
Upd. Tried using .contains
as suggested by cfrick in an answer, like this:
(defmethod call-fn "contains" [_ item items] (.contains items item))
This doesn't raise a runtime error, yet the output is always false
now. println
debugging reveals this:
(defmethod call-fn "contains" [_ item items]
(println item)
(println items)
(.contains items item))
1
#object[java.util.Collections$UnmodifiableRandomAccessList 0x778ca8ef [9, 4, 1, 6, 3]]
Why?