Отправка мультиметода по пространству имен карты с пространством имен - PullRequest
0 голосов
/ 30 апреля 2018

Можно ли выполнить диспетчеризацию на основе пространства имен карты пространства имен, т.е. #:<this-thing>{}? Без хаков, таких как печать или проверка префиксов ключей?

Я считаю, что последний хакерский, потому что префикс ключа может быть переопределен:

(:qux/bar #:qux{:bar :baz}); => :baz
(:foo/bar #:qux{:foo/bar :baz}); => :baz
(:qux/bar #:qux{:foo/bar :baz}); => nil

Ответы [ 2 ]

0 голосов
/ 30 апреля 2018

Карта может содержать все определенные ключи ключевых слов из определенного пространства имен или может содержать комбинацию неквалифицированных ключей или определенных ключей из нескольких пространств имен. Вот функция для получения набора всех пространств имен (в виде ключевых слов) из квалифицированных ключевых слов на карте:

(defn key-namespaces
  "Returns set of all namespaces of keys in m."
  [m]
  (->> (keys m)
       (keep (comp keyword namespace))
       (set)))

Теперь вы можете использовать это как dispatch-fn для мультиметода:

(defmulti do-thing key-namespaces)
(defmethod do-thing #{:foo} [m] (prn m))
(do-thing #:foo{:bar 1})
;; #:foo{:bar 1}
(foo {:bar/bar 1})
;; no multimethod found exception

Вы можете указать несколько префиксов пространства имен в этом наборе, или вы можете использовать другой dispatch-fn в зависимости от вашего варианта использования.

0 голосов
/ 30 апреля 2018

Это невозможно, поскольку это только визуальное представление карты, созданной writer. Вы должны будете выполнить проверки самостоятельно, если все ключи на вашей карте имеют одно и то же пространство имен. Также последний пример не будет создан автором - он будет генерировать литерал карты пространства имен только тогда, когда все ключи будут использовать одно и то же пространство имен .

...