Подтвердить что ты не робот

Каковы общие соглашения об использовании пространств имен в Clojure?

У меня возникают проблемы с поиском хороших советов и распространенных практик использования пространств имен в Clojure. Я понимаю, что пространства имен не совпадают с пакетами Java, поэтому я пытаюсь разделить условные обозначения в Clojure, что кажется удивительно трудным для определения.

Я думаю, что у меня неплохая идея, как разделять функции на clj файлы и даже грубо, как я хочу организовать эти файлы в каталогах. Но помимо этого у меня возникли проблемы с поиском механики для моей среды разработчиков. Некоторые взаимосвязанные вопросы:

  • Использовать ли те же соглашения о единственности для пространств имен Clojure, как я обычно использовал бы для пакетов Java? [т.е. backward-company-domain.project.subsystem]
  • Следует ли сохранять мои файлы в структуре каталогов, которая соответствует моим пространствам имен? [ala Java]
  • Если у меня несколько пространств имен, мне нужно скомпилировать весь мой код в банку и добавить его в мой путь к классам, чтобы сделать его доступным?
  • Должно ли каждое пространство имен составлять одну банку? Или я должен создать единую банку, содержащую код clj из многих пространств имен?

Спасибо...

4b9b3361

Ответ 1

  • Я думаю, это нормально, если вы думаете, что это помогает, но многие проекты Clojure этого не делают - ср. Compojure (используя компоновку верхнего уровня и различные компоненты. * Ns для определенной функциональности), Ring, Leiningen... Clojure сам использует clojure. * (И clojure.contrib. * Для вкладчиков), но я полагаю, что это особый случай.

  • Да! Вы абсолютно должны это сделать, иначе Clojure не сможет найти ваши пространства имен. Также обратите внимание, что вы не используете символ подчеркивания в именах имен или дефис в именах файлов и везде, где вы используете дефис в имени пространства имен, вы должны использовать знак подчеркивания в имени файла (так что ns my.cool-project определяется в файле называется cool_project.clj в каталоге с именем my).

  • Вам нужно убедиться, что все ваши вещи находятся в пути к классам, но неважно, если это в банке, несколько банок, смесь банок и каталогов в файловой системе... Пока это подчиняется правильным соглашениям об именах (ваш пункт № 2), вы должны быть в порядке.

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

    Вам все равно придется иногда использовать компиляцию AOT, особенно в некоторых сценариях взаимодействия Java - документация соответствующих функций/макросов всегда упоминает об этом. Есть примеры вещей, требующих AOT в clojure.contrib; Я никогда не нуждался в этом, поэтому я не могу предоставить много деталей.

  • Я бы сказал, что вы должны использовать банки для функциональных блоков кода. Например. Compojure и Ring получают в виде отдельных банок, содержащих множество пространств имен, которые вместе составляют весь пакет. Кроме того, clojure.contrib особенно упакован как одна банка с несколькими несвязанными библиотеками; но это снова может быть особым случаем.

    С другой стороны, единая банка, содержащая весь код проекта вместе со своими зависимостями, иногда может быть полезна для развертывания. Проверьте инструмент создания Leiningen и его объект uberjar, если вы считаете, что это может быть полезно для вас.

Ответ 2

  • Строго говоря, не обязательно, хотя многие проекты Java также отказались от этого соглашения, особенно для внутренних проектов или частных API. Однако избегайте односегментных пространств имен, что приведет к генерации файлов классов в пакете по умолчанию.
  • Да.

Что касается 3 и 4, упаковка и компиляция AOT полностью ортогональны вопросу об условных обозначениях пространства имен.