Как переименовать с помощью (ns (: require: refer))

Я понимаю, что сейчас рекомендуется использовать require :refer вместо use в макросе ns. Например, do:

(ns example.core 
  (:require [clj-json.core :refer [parse-string]]))

вместо

(ns example.core 
  (:use [clj-json.core :only [parse-string]]))

Каков рекомендуемый способ работы с :rename, который поддерживает use? В частности, скажем, я хочу require clojure.data.zip и переименуйте функции ancestors и descendants, которые конфликтуют с clojure.core.

Другими словами, я хотел бы знать эквивалент require для

(:use 
  [clojure.data.zip :rename {ancestors xml-ancestors, 
                             descendants xml-descendants})

Ответ 1

Вы :require за один шаг, а затем :refer с :rename в следующем.

(ns foo
  (:require clojure.data.zip)
  (:refer [clojure.data.zip :rename {ancestors xml-ancestors,
                                     descendants xml-descendants})

:use всегда была сокращением для :require + :refer, и теперь опция :refer для :require является сокращением для простейшего типа refer.

Ответ 2

(ns foo
  (:require [clojure.data.zip :refer [ancestors descendants] :rename {ancestors xml-ancestors descendants xml-descendants}]))

Ответ 3

Отказ от ответственности: я не знаю "рекомендуемый" способ сделать это. Я знаю только, как я это сделаю. Мое решение не может быть идиоматическим Clojure, и я был бы удивлен, если бы никто не согласился с лучшим ответом.


Вот что я сделал бы: :require пакет и псевдоним с помощью :as:

(ns some.big.name.space
  (:require [clojure.data.zip  :as  cdz])
  ... some more imports, maybe ...)

Затем символы могут быть доступны с использованием указанного префикса и не конфликтуют с любыми символами в моем пространстве имен some.big.name.space:

(def some-list [cdz/ancestors cdz/descendants ancestors descendants])

Если псевдоним короткий, мне трудно называть его, и я чувствую, что мой код ясен - cdz/ - это хороший визуальный сигнал, что символ является импортом.

Я знаю, что это на самом деле не отвечает на ваш точный вопрос - как использовать :rename с :require - но я чувствую, что стоит упомянуть, потому что он позволяет избежать загрязнения моих пространств имен, и мне не нужно путаться с Clojure механизмами разрешения символов.

Ответ 4

Если вам нужно переименовать функции или макросы из ядра Clojure, используйте это:

(ns foo
  "Contains foo functionality."
  (:refer-clojure :rename {map core-map}))