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.core
namespace 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.core
namespace.
Salah satunya adalah file utama, dinamai sesuai dengan nama namespace sehingga akan ditemukan ketika seseorang menyebutkannya di a :use
atau :require
. Dalam hal ini file utama adalah clojure/core.clj
, dan dimulai dengan ns
formulir. Di sinilah Anda harus meletakkan semua konfigurasi namespace Anda, terlepas dari file mana yang mungkin membutuhkannya. Ini biasanya termasuk :gen-class
juga, 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 load
untuk membawa file pembantu Anda. Di clojure.core
dalamnya 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 .clj
akhiran.
Setiap file pembantu harus dimulai dengan mendeklarasikan namespace mana yang mereka bantu, tetapi harus melakukannya dengan menggunakan in-ns
fungsi 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-class
fungsi 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 :private
vars 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.