Фон: ns-interns
против ns-map
ns-interns
возвращает карту Vars, первоначально интернированную в данном пространстве имен. Невозможно взять Var из одного пространства имен и отобразить его в выводе другого пространства имен ns-interns
. Таким образом, если вы хотите, чтобы Var появлялся здесь, вам нужно использовать intern
или def
.
Напротив, ns-map
является более фундаментальным примитивом, который возвращает потенциально большую карту, которая включает в себя «собственные интерны», но также и переменные из других пространств имен, введенных через :require :refer
и импортированных классов Java.
(Это более фундаментально, потому что ns-interns
работает, вызывая ns-map
и фильтруя его так, что сохраняются только Vars, изначально интернированные в данном пространстве имен. Это возможно, потому что Vars отслеживают пространство имен, в котором они были созданы, если любое и любое изначально присвоенное имя. 1 )
Карта, которую возвращает ns-map
, - это та, с которой ns-unmap
удаляет сопоставления. Обратите внимание, что ns-map
и ns-unmap
не делают различий между "собственными переменными" и переменными из других пространств имен. Записи var на этой карте создаются, когда вы используете intern
или def
, но также и при сопоставлении Vars из других пространств имен. Если последнее - то, что вы хотите сделать, есть несколько способов сделать это.
Добавление переменных из других пространств имен в данное пространство имен ns-map
Стандартным способом является использование :require :refer … :rename …
или :use :only … :rename …
в форме ns
или clojure.core/refer :only … :rename …
при REPL:
user=> (refer 'clojure.string :only '[lower-case] :rename '{lower-case lc})
nil
user=> (lc "ASDF")
"asdf"
NB. Аргумент, следующий за :only
, представляет собой набор символов без пространств имен, которые присваивают именам переменные, которые вы хотите добавить, в их собственном пространстве имен - исходных именах, а карта :rename
содержит исходные имена в ключевой позиции и ваши замещающие имена. в положении значения.
Если вы счастливы принять оригинальное имя, вы можете пропустить :rename
.
Также можно вызвать clojure.core/require
или clojure.core/use
, что обеспечит загрузку пространства имен и затем refer
Vars, которые вам нужны. Синтаксис такой же, как в форме ns
- см. Ниже, - за исключением того, что наборы символов, следующие за :only
и :rename
, должны быть заключены в кавычки, как при вызове refer
выше.
В ns
форме вы бы сказали
(:require [clojure.string :refer [lower-case] :rename {lower-case lc}])
или
(:use [clojure.string :only [lower-case] :rename {lower-case lc}])
:require
имеет тенденцию быть предпочтительным в наши дни как вопрос стиля.
1 Для полноты картины можно создать переменные, которые не считают себя принадлежащими к какому-либо пространству имен или имеющему какое-либо конкретное имя, но нет общедоступного API для добавления их в любую карту пространства имен, как прямо сейчас; на самом деле их присутствие в карте пространства имен может привести к некоторым странным действиям.