Чи можна розділити простір імен Clojure на кілька вихідних файлів, виконуючи компіляцію заздалегідь :gen-class
? Як це зробити (:main true)
і (defn- ...)
вступити в гру?
Відповіді:
Звичайно, ви можете, насправді clojure.core
сам простір імен розділений таким чином і забезпечує хорошу модель, якій ви можете слідувати, заглянувши в src/clj/clojure
:
core.clj
core_deftype.clj
core_print.clj
core_proxy.clj
..etc..
Всі ці файли беруть участь у побудові єдиного clojure.core
простору імен.
Одним з них є основний файл, названий таким чином, щоб він відповідав імені простору імен, щоб його можна було знайти, коли хтось згадає його в :use
або :require
. У цьому випадку основним є файл clojure/core.clj
, і він починається з ns
форми. Тут слід розмістити всю конфігурацію простору імен, незалежно від того, який з інших ваших файлів може їм знадобитися. Зазвичай це включає :gen-class
також, тому щось на зразок:
(ns my.lib.of.excellence
(:use [clojure.java.io :as io :only [reader]])
(:gen-class :main true))
Потім у відповідних місцях у вашому первинному файлі (найчастіше все в кінці) використовуйте load
для введення ваших допоміжних файлів. У clojure.core
це виглядає наступним чином :
(load "core_proxy")
(load "core_print")
(load "genclass")
(load "core_deftype")
(load "core/protocols")
(load "gvec")
Зверніть увагу, що вам не потрібен поточний каталог як префікс, а також не потрібен .clj
суфікс.
Кожен з допоміжних файлів повинен розпочинатись із декларування, якому простору імен вони допомагають, але це слід робити за допомогою in-ns
функції. Отже, для прикладу простору імен вище, допоміжні файли починаються з:
(in-ns 'my.lib.of.excellence)
Це все, що потрібно.
Оскільки всі ці файли будують єдиний простір імен, кожна визначена вами функція може знаходитись у будь-якому з основних або допоміжних файлів. Це, звичайно, означає, що ви можете визначити свої gen-class
функції в будь-якому файлі, який хочете:
(defn -main [& args]
...)
Зверніть увагу, що звичайні правила порядку визначення Clojure як і раніше застосовуються до всіх функцій, тому вам потрібно переконатися, що будь-який файл, що визначає функцію, завантажується, перш ніж намагатися використовувати цю функцію.
Ви також запитали про (defn- foo ...)
форму, яка визначає приватну функцію простору імен. Функції, визначені таким чином, а також інші :private
vars видно з простору імен, де вони визначені, тому основний та всі допоміжні файли матимуть доступ до приватних vars, визначених у будь-якому з завантажених до цього часу файлів.