أفضل الممارسات في بناء ونشر تطبيقات clojure: دروس جيدة؟

StackOverflow https://stackoverflow.com/questions/2391711

سؤال

أنا جديد على Clojure ، وبدأت في تجربة بناء تطبيق.

حتى الآن ، كل ما رأيته حول البرامج التعليمية حول تجميع برامج clojure ينطوي على التفاعل. على سبيل المثال ، "قم بتحميل repl و type (ملف التحميل" هذا أو هذا ") لتشغيله. هذا جيد ، لكنه ليس كافيًا.

أنا معتاد على تعبيرات اللغات التي تديرها التحرير مثل C أو Delphi ، لدرجة أنني كنت مدفوعًا غريزيًا لإجراء تعديلات ، ثم ضرب "MX Compile".

المشكلة هي أن "Lein Uberjar" ، الذي أفهمه هو ما يعادل "Make" ، بطيئًا بشكل مؤلم في التنفيذ حتى بالنسبة لعالم مرحبًا. لذلك سأضطر إلى معرفة كيفية عمل هذه الأشياء "التطوير التفاعلي" ، والتوقف عن استخدام Uberjar كما لو كان ذلك سريعًا ، وحفظه فقط لنهاية اليوم.

شيء آخر لاحظته أثناء بناء (باستخدام Lein Uberjar) هو أن تطبيق واجهة المستخدم الرسومية الصغيرة التي أعمل عليها على إطارات الملوثات العضوية الثابتة في عملية التجميع ، كما لو كانت التنفيذ أثناء التجميع. يبدو أنه غير بديهي بعض الشيء بالنسبة لي ؛ إنه ليس مشابهًا تمامًا "صنع" كما اعتقدت.

أعلم أن طريقة Lisp لتطوير الأشياء تعمل بشكل تفاعلي في REPL ، وأنا لا أحاول تغيير ذلك: أود التكيف مع طريقة الحياة هذه. لسوء الحظ ، لم أر سوى القليل في شكل وثائق حول كيفية القيام بذلك. على سبيل المثال ، كيفية إعادة ضبط الحالة الحالية للجهاز. يبدو أنه نوع من الفوضى فقط للاستمرار في تجميع قصاصات فردية أثناء الطيران دون أن تكون قادرًا على القيام بنوع من إعادة التعيين.

يبدو أن معظم البرامج التعليمية التي رأيتها على Clojure (و LISP) بشكل عام تركز على القرصنة في Repl. تظل أفضل الممارسات على نشر الطلبات لغزا بالنسبة لي. مستخدمي سيكونون مستخدمين ؛ لن يكونوا مطورين سيقومون بتحميل الملفات في استبدال.

إذن هذا هو سؤالي: أي موارد للحصول على معلومات أو دروس جيدة في عملية إنشاء تطبيق Clojure بأكمله ، بما في ذلك النشر؟

(ملاحظة: لدي جميع المتطلبات المسبقة المثبتة والعمل (على سبيل المثال emacs ، الوحل ، لينينينين ، إلخ) ، لذلك ليس هذا سؤالًا حول ذلك).

هل كانت مفيدة؟

المحلول

بضع تلميحات سريعة ، ثم بعض الروابط:

لا تستخدم lein uberjar أثناء التنمية تفضل lein jar. الفرق هو ذلك lein uberjar يضع كل تبعياتك في المولدة jar (بما في ذلك Clojure نفسها) ، بحيث تكون جرة واحدة الخاصة بك عبارة عن حزمة محتوية على نفسها تمامًا مع تطبيقك في الداخل ؛ lein jar فقط الجرار رمز الخاص بك. ال uberjar يحتوي النهج على فوائد واضحة للنشر ، ولكن للتنمية ، يجب أن تكون قادرًا على استخدام ClassPath المناسب عند تشغيل تطبيقك ، وتوفير الوقت اللازم لإعداد Uberjar. إذا كنت لا ترغب في إدارته يدويًا على تشغيل ClassPath للاختبار ، تحقق من lein run توصيل في.

أيضًا ، على الأرجح ، يجب ألا يتم تجميع غالبية الكود الخاص بك. AOT ضروري في بعض سيناريوهات Java interop ، ولكن في معظم الأحيان يجلب واحدة دفعة طفيفة في سرعة بدء التشغيل والمشاكل المزعجة مع التوافق الثنائي مع الإصدارات المختلفة من clojure. أفترض أن القضية الأخيرة ليست ذات صلة بـ uberjar-نوع التطبيق المستقل من المشروع ، ولكن يجب ترك أي رمز مكتبة على الأقل ليكون Jit-ED إذا كان ذلك ممكنًا. مع Lininingen ، يمكنك وضع ملف :namespaces جملة في defproject شكل في project.clj لتحديد مساحات الأسماء التي سيتم تجميعها ؛ كل ما تغادره سيكون حاليا jit-ed افتراضيا. تستخدم الإصدارات القديمة من Lininingen لتجميع كل شيء بشكل افتراضي ، وهو في الواقع سبب وجيه للترقية!

أما بالنسبة للنوافذ التي ظهرت أثناء التجميع ، فأنا أعتقد أنك إما تقوم بتشغيل رمز التنافس أثناء وقت توسيع الماكرو أو خارج أي تعريف وظيفي أو بناء مشابه. (شيء مثل أ (println "Foo!") في المستوى الأعلى.) هذا مجرد شيء لا يجب عليك فعله ، أفترض - ما لم تكن تخطط لتشغيل الكود الخاص بك كنص ، على أي حال. لتجنب المشكلة ، قم بلف رمز التأثير الجانبي في تعريفات الوظائف وتوفير نقطة دخول إلى تطبيقك باستخدام :main جملة في project.clj. (إذا قلت :main foo, ، ثم -main وظيفة من foo سيتم استخدام مساحة الاسم كنقطة دخول إلى تطبيقك. هذا هو الافتراضي ، على أي حال ، وعلى الأقل المذكورة أعلاه lein run يبدو أن الاسم متشددين - لست متأكداً من لين نفسه.)

أما بالنسبة لإعادة ضبط حالة الاستبدال - يمكنك إعادة تشغيله فقط. مع SLIME ، سيفعل MX Slime-Restart-Inferior-LISP ذلك تمامًا مع الحفاظ على جميع الحالة الأخرى لجلسة EMACs الخاصة بك.

انظر أيضًا هذه المناقشات حول مجموعة Clojure Google:

  1. clojure لإدارة النظام
  2. prepping clojure للتغليف (كان: رد: clojure لإدارة النظام)
  3. Lininingen ، Clojure والمكتبات: ماذا أفتقد؟

نصائح أخرى

لا ، أنت لا تدخل وظائف على Repl.

يمكنك تحرير ملفاتك المصدر ، كالمعتاد. تتمثل ميزة LISP في أن لديك النظام يعمل في الخلفية في نفس الوقت ، بحيث يمكنك تجميع الوظائف الفردية من ملف المصدر الخاص بك ووضعها في نظام التشغيل ، أو حتى استبدالها هناك.

إذا كنت تستخدم الوحل ، فأنت تضغط C-c C-c في ملف المصدر الخاص بك لتجميع وتحميل الوظيفة عند النقطة. يمكنك بعد ذلك التبديل إلى REPL للاختبار واستكشاف ، ولكن أي شيء تريد أن تستمر كمصدر ، يمكنك وضعه في ملفاتك المصدر.

عادةً ما تبدأ البرامج التعليمية بكتابة الأشياء على REPL ، لأنه لا يوجد الكثير الذي تحتاجه إلى الإعداد لهذا ، ولكن التطوير الجاد يدمج نظام التشغيل وإدارة الملفات المصدر.


فقط لتوضيح ، سير العمل المعتاد (أنا أستخدم LISP المشترك ، لكن Clojure متشابهة) مثل هذا:

  • ابدأ emacs
  • M-x slime لبدء الوحل ، نظام LISP ، وتوصيل الاثنين عبر Swank
  • , (أمر) load-system foo لتحميل المشروع الحالي (تجميع فقط إذا لزم الأمر) في الصورة
  • C-x b قم بالتبديل إلى المخزن المؤقت للمصدر
  • C-c ~ اجعل الدليل المصدر الدليل الحالي وحزمة المصدر الحزمة الحالية للاستبدال

الآن ، أقوم بإعداد نظامي يعمل في الخلفية. العمل بعد ذلك:

  • تغيير أو إضافة وظيفة أو تعريف فئة
  • C-c C-c لتجميعها وتحميلها في الصورة
  • التبديل إلى الاستبدال ، اختبار
  • تصحيح

لا توجد توقف كبير في التجميع ، لأنني لم أتجمع أبدًا كل شيء في وقت واحد ، فقط تعريفات فردية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top