कई फाइलों पर क्लोजर नेमस्पेस का विभाजन


91

क्या आगे के समय संकलन के साथ कई स्रोत फ़ाइलों पर क्लोजर नामस्थान को विभाजित करना संभव है :gen-class? कैसे करते हैं (:main true)और (defn- ...)खेलने में आते हैं?

जवाबों:


137

अवलोकन

निश्चित रूप से आप कर सकते हैं, वास्तव में 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]
  ...)

ध्यान दें कि क्लोजर के सामान्य ऑर्डर-ऑफ-डेफिनिशन नियम अभी भी सभी कार्यों के लिए लागू होते हैं, इसलिए आपको यह सुनिश्चित करने की आवश्यकता है कि किसी फ़ंक्शन को परिभाषित करने से पहले उस फ़ंक्शन का उपयोग करने का प्रयास करने से पहले जो भी फ़ाइल लोड होती है।

निजी वर

आपने उस (defn- foo ...)फॉर्म के बारे में भी पूछा है जो एक नाम स्थान-निजी फ़ंक्शन को परिभाषित करता है। इस तरह परिभाषित किए गए फ़ंक्शंस और साथ ही अन्य :privateसंस्करण नामस्थान के भीतर से दिखाई देते हैं जहां वे परिभाषित हैं, इसलिए प्राथमिक और सभी सहायक फ़ाइलों में अब तक लोड की गई किसी भी फ़ाइल में परिभाषित निजी संस्करण तक पहुंच होगी।


3
बहुत अच्छा, पूरा जवाब! BTW, मैं जॉय ऑफ क्लोजर के माध्यम से अपने पहले पास पर लगभग समाप्त हो गया हूं । महान पुस्तक!
राल्फ

इस उत्तर को साझा करने के लिए धन्यवाद। क्या इसे 2 साल बाद भी एक अच्छा अभ्यास माना जाता है? (मैं जानता हूं कि चीजें तेजी से बदलती हैं।) मैं देखता हूं कि क्लोजर खुद अभी भी इस तकनीक का उपयोग करता है।
डेविड जे।

9
आज के रूप में यह अभी भी सबसे अच्छा अभ्यास है यदि आप सुनिश्चित हैं कि आप एकल नाम स्थान बनाने के लिए कई फाइलें चाहते हैं। हालाँकि, यह अब की तुलना में कम आम हो सकता है। एक विकल्प एक फ़ाइल में आपके ns के सभी सार्वजनिक संस्करणों को परिभाषित करने के लिए हो सकता है, और सभी सहायक संस्करणों और कार्यों को एक अलग "कार्यान्वयन" नामस्थान पर ले जा सकता है। तकनीकी रूप से var सार्वजनिक रूप से सार्वजनिक होंगे, लेकिन ns docstring यह दर्शाता है कि वे दस्तावेजित API का हिस्सा नहीं हैं और यह पर्याप्त होना चाहिए।
चॉसर

1
क्या हम जानते हैं कि किसी भी सामान्य क्लोजर टूलिंग में मल्टी-फाइल नेमस्पेस समझने की समस्या है? लें? बूट? साइडर? nREPL? Kibit? ईस्टवुड? Cloverage? आदि ...
डिडिएर ए।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.