Каковы общие соглашения для использования пространств имен в Clojure? - PullRequest
50 голосов
/ 08 февраля 2010

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

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

  1. Использую ли я те же соглашения об уникальности для пространств имен Clojure, которые я обычно использовал бы для пакетов Java? [т.е. backwards-company-domain.project.subsystem]
  2. Должен ли я сохранять свои файлы в структуре каталогов, которая соответствует моим пространствам имен? [аля Ява]
  3. Если у меня несколько пространств имен, нужно ли мне скомпилировать весь мой код в jar-файл и добавить его в мой путь к классам, чтобы сделать его доступным?
  4. Должно ли каждое пространство имен компилироваться в одну банку? Или я должен создать одну банку, которая содержит код clj из многих пространств имен?

Спасибо ...

Ответы [ 2 ]

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

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

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

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

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

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

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

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

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

...