Apakah mungkin untuk membagi namespace Clojure menjadi beberapa file sumber saat melakukan kompilasi sebelumnya :gen-class? Bagaimana (:main true)dan (defn- ...)ikut bermain?
Jawaban:
Tentu Anda bisa, pada kenyataannya clojure.corenamespace itu sendiri dibagi dengan cara ini dan menyediakan model yang baik yang dapat Anda ikuti dengan melihat di src/clj/clojure:
core.clj
core_deftype.clj
core_print.clj
core_proxy.clj
..etc..
Semua file ini berpartisipasi untuk membangun satu clojure.corenamespace.
Salah satunya adalah file utama, dinamai sesuai dengan nama namespace sehingga akan ditemukan ketika seseorang menyebutkannya di a :useatau :require. Dalam hal ini file utama adalah clojure/core.clj, dan dimulai dengan nsformulir. Di sinilah Anda harus meletakkan semua konfigurasi namespace Anda, terlepas dari file mana yang mungkin membutuhkannya. Ini biasanya termasuk :gen-classjuga, jadi sesuatu seperti:
(ns my.lib.of.excellence
(:use [clojure.java.io :as io :only [reader]])
(:gen-class :main true))
Kemudian di tempat yang tepat di file utama Anda (paling umum semua di bagian akhir) gunakan loaduntuk membawa file pembantu Anda. Di clojure.coredalamnya terlihat seperti ini:
(load "core_proxy")
(load "core_print")
(load "genclass")
(load "core_deftype")
(load "core/protocols")
(load "gvec")
Perhatikan bahwa Anda tidak memerlukan direktori saat ini sebagai awalan, Anda juga tidak memerlukan .cljakhiran.
Setiap file pembantu harus dimulai dengan mendeklarasikan namespace mana yang mereka bantu, tetapi harus melakukannya dengan menggunakan in-nsfungsi tersebut. Jadi untuk contoh namespace di atas, semua file helper akan dimulai dengan:
(in-ns 'my.lib.of.excellence)
Hanya itu yang dibutuhkan.
Karena semua file ini membangun satu namespace, setiap fungsi yang Anda tetapkan dapat berada di file utama atau helper mana pun. Ini tentu saja berarti Anda dapat menentukan gen-classfungsi Anda di file apa pun yang Anda inginkan:
(defn -main [& args]
...)
Perhatikan bahwa aturan urutan definisi normal Clojure masih berlaku untuk semua fungsi, jadi Anda perlu memastikan bahwa file apa pun yang mendefinisikan suatu fungsi dimuat sebelum Anda mencoba menggunakan fungsi itu.
Anda juga bertanya tentang (defn- foo ...)formulir yang mendefinisikan fungsi namespace-private. Fungsi yang didefinisikan seperti ini dan juga :privatevars lainnya terlihat dari dalam namespace tempat mereka didefinisikan, sehingga file utama dan semua helper akan memiliki akses ke vars pribadi yang ditentukan dalam file mana pun yang dimuat sejauh ini.