Я написал функцию, которая выбирает только те ключи карты, которые названы в определенной схеме:
(ns foo.schema
(:require [schema.core :as s]))
(defn select-schema
"Given a schema and a map m, selects only the keys of m that are named in the schema."
[m schema]
(let [optional? #(instance? schema.core.OptionalKey %)
wildcard? #(= s/Keyword %)]
(if (some wildcard? (keys schema))
m ; the schema allows any keyword as a key, so just return the map
(let [ks (->> schema keys (map #(if (optional? %) (:k %) %)))]
(select-keys m ks)))))
Это отлично работает в моих модульных тестах:
(testing "Required key and wildcard"
(let [schema {:foo s/Str, s/Keyword s/Any}]
(is (= {:foo "Yup", :bar 42, :baz true} (select-schema {:foo "Yup", :bar 42, :baz true} schema)))
(is (= {:foo "Yup", :bar 42} (select-schema {:foo "Yup", :bar 42} schema)))
(is (= {:foo "Yup"} (select-schema {:foo "Yup"} schema)))))
Однако, когда я использую foo.schema/select-schema
в совершенно отдельном проекте (например, lein install
в моем проекте foo, чтобы создать банку, вставить ее в мой ~/.m2/repository
и назвать как зависимость), я получаю ClassNotFoundException
:
Exception in thread "main" java.lang.ExceptionInInitializerError, compiling:(insurrection/test/handler.clj:1:1)
at clojure.lang.Compiler.load(Compiler.java:7142)
...
Caused by: java.lang.ExceptionInInitializerError
at foo.schema__init.load(Unknown Source)
at foo.schema__init.<clinit>(Unknown Source)
at java.lang.Class.forName0(Native Method)
...
Caused by: java.lang.ClassNotFoundException: schema.core.OptionalKey
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
...
Я просмотрел исходный код Prismatic Schema и обнаружил, что OptionalKey
— это тип дезаписи. Небольшое гугление показало, что defrecord генерирует класс Java, который иногда необходимо импортировать после запроса определяющего его пространства имен, но попытка сделать это в проекте, содержащем foo.schema
, не имеет никакого значения: он работает в модульных тестах, но не работает в другом проекте, который использует foo
в качестве зависимости.