سؤال

ما الفرق بين الكعك وليينينين؟

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

المحلول

تستمر هذه الإجابة في الحصول على الاهتمام ، على الأرجح كمرجع لـ Lininingen في Stackoverflow ، لذلك تم الآن تحريره بشكل كبير لتحديثه لعام 2014.

تم دمج Lininingen و Cake في عام 2011. Lininingen (الإصدار 2) هو الآن أداة أتمتة Clojure الفعلية.

لينينينينهو أداة بناء ومدير التبعية لـ Clojure والتي تتضمن القدرة على إعداد استبدال تفاعلي مع classpath المكونة بشكل مناسب ومع جميع تبعيات Java و Clojure التي تم الحصول عليها بطريقة آلية من مستودعات Maven و/أو المجتمع clojars.

كانت Cake مشابهة جدًا لـ Lininingen (وصولاً إلى استخدام نفس تنسيق ملف Project.clj في ذلك الوقت) ولكن حاولت تجنب الكثير من النفقات العامة بدء التشغيل من خلال الحفاظ على JVMs المستمرة في الخلفية. كان هذا أكثر استجابة ولكن الراحة المتداولة للأخطاء بسبب الحالة المتراكمة في العمليات المستمرة (تعريفات الوظيفة القديمة المعلقة حول وما إلى ذلك) على المسار النموذجي للتطوير التكراري القائم على الاسترداد. تبين أن هذا صفقة سيئة.

أدت التجربة مع لينينينج والرغبة المستمرة في أوقات بدء التشغيل بشكل أسرع إلى عدد من التوصيات والمناهج لتسريع الأمور: https://github.com/technomancy/leiningen/wiki/faster

نصائح أخرى

الفرق الرئيسي هو في الطريقة التي يتم بها تنفيذ المهام.

نهج Cake هو "من الصعب تمديد الوظائف بعد تعريفها ، لذلك دعونا نخترع آلية جديدة للمهام بدلاً من استخدام الوظائف" ، مما أدى إلى الماكرو المهمل.

نهج Lininingen هو "من الصعب تمديد الوظائف بعد تعريفها ، لذلك يجب أن نقدم طريقة للقيام بذلك بسهولة ؛ وبهذه الطريقة يمكننا استخدام وظائف للمهام ونكون قادرين أيضًا على توسيع الأشياء التي ليست مهامًا" ، والتي يتيح لك تطبيق جميع مزايا التوافق للوظائف مع المهام.

كما ذكر أليكس ، فإن الاختلاف الأكثر لفتا هو السرعة من سطر الأوامر. يستخدم Cake JVM المستمر ، لذلك لا تواجه سوى تشغيل JVM النفقات العامة عند تشغيل مهمة داخل مشروعك لأول مرة. إذا كنت لا تستخدم EMACS + Slime + Clojure-Test-Mode ، فقد يكون هذا موعدًا كبيرًا. على سبيل المثال ، تعمل مجموعة كبيرة من الاختبارات على أحد مشاريعي في 0.3 ثانية في Cake ، مقابل 11.2s في لين.

بصرف النظر عن الأداء ، فإن الفكرة الأساسية وراء Cake هي نموذج مهمة التبعية. يتم تشغيل كل مهمة فقط مرة واحدة في بناء معين ، مع الأخذ في الاعتبار جميع المتطلبات المسبقة متعدية في الرسم البياني التبعية. إليك مثال من مقال مارتن فاولر عن Rake في بناء جملة الكيك ، والذي يذهب مباشرة في مشروعك.

(deftask code-gen
  "This task generates code. It has no dependencies."
  (println "generating code...")
  ...)

(deftask compile #{code-gen}
  "This task does the compilation. It depends on code-gen."
  (println "compiling...")
  ...)

(deftask data-load #{code-gen}
  "This task loads the test data. It depends on code-gen."
  (println "loading test data...")
  ...)

(deftask test #{compile data-load}
  "This task runs the tests. It depends on compile and data-load."
  (println "running tests...")
  ...)

للقيام بنفس الشيء في Lininingen ، سيتعين عليك أولاً إنشاء دليل Lininingen في مشروعك مع 4 ملفات: code_gen.clj ، compile.clj ، data_load.clj ، و my_test.clj.

src/leiningen/code_gen.clj

(ns leiningen.code-gen
   "This task generates code. It has no dependencies.")

(defn code-gen []
  (println "generating code..."))

src/leiningen/my_compile.clj

(ns leiningen.my-compile
  "This task does the compilation. It depends on code-gen."
  (:use [leiningen.code-gen]))

(defn my-compile []
  (code-gen)
  (println "compiling..."))

src/leiningen/data_load.clj

(ns leiningen.data-load
  "This task loads the test data. It depends on code-gen."
  (:use [leiningen.code-gen]))

(defn data-load []
  (code-gen)
  (println "loading test data..."))

src/lininingen/my_test.clj

(ns leiningen.my-test
  "This task runs the tests. It depends on compile and data-load."
  (:use [leiningen.my-compile]
        [leiningen.data-load]))

(defn my-test []
  (my-compile)
  (data-load)
  (println "running tests..."))

يتوقع المرء ...

generating code...
compiling...
loading test data...
running tests...

لكن كل من تحميل البيانات و my-compile يعتمدان على الكود ، وبالتالي فإن ouput الفعلي الخاص بك هو ...

generating code...
compiling...
generating code...
loading test data...
running tests...

سيكون عليك أن تذكر الجيل المسموح به لمنع تشغيله عدة مرات:

(ns leiningen.code-gen
   "This task generates code. It has no dependencies.")

(def code-gen (memoize (fn []
                         (println "generating code..."))))

انتاج:

generating code...
compiling...
loading test data...
running tests...

وهو ما نريد.

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

يمنحك لين وظيفة واضحة كمهمة ، ولكن مع القيد المضافة بأنه يجب أن يكون له مساحة اسم خاصة به في SRC. إذا كانت المهمة تعتمد عليها ، فستكون في مساحة اسم منفصلة ، ويجب استخدامها/طلبها الآخر ns دقيق. تبني الكعكة تبدو أكثر إبداعًا وموجزة بالمقارنة.

الفرق الرئيسي الآخر هو كيفية إلحاق المهام. دعنا نقول أننا أردنا أن نضيف my-test كشرط مسبق لكعكة/لين في jar مهمة. في الكعكة ، يمكنك استخدام deftask الماكرو لإلحاق نماذج المهمة وتبعياتها.

(deftask jar #{my-test})

يستخدم لين روبرت هووك لإلحاق المهام. إنها مكتبة رائعة حقًا ، سميت باسم PhilshoSer المفضل لدى الجميع ، لكنها تتطلب ماكرو لإيجاز deftask.

(add-hook #'leiningen.jar/jar (fn [f & args]
                                (my-test)
                                (apply f args)))

كعكة لديها أيضا فكرة مشروع عالمي. يمكنك إضافة عمليات الاعتماد الخاصة بالمستخدم ، مثل Swank ، إلى ~/.cake/project.clj واحصل عليها عبر جميع مشاريعك. يستخدم المشروع العالمي أيضًا لبدء الاستبدال خارج مشروع للتجربة. ينفذ LEIN ميزات مماثلة من خلال دعم تكوين المستخدم في ~/.lein/init.clj, والمكونات الإضافية العالمية في ~/.lein/plugins. بشكل عام ، لدى Lein حاليًا نظامًا بيئيًا إضافيًا أكثر ثراءً من Cake ، ولكن الكعك يتضمن المزيد من المهام خارج الصندوق (الحرب ، Deploy ، وتجميع Java ، وتبعيات أصلية ، و Clojars ، و Swank). قد يكون CLJR أيضًا يستحق المراجعة ، إنه في الأساس مجرد مشروع عالمي مع مدير الحزمة ، ولكن بدون إمكانات البناء (ليس لدي أي خبرة في ذلك).

الاختلاف الحقيقي غير المسموح به هو تعريف المهمة ، كما أشار التقنية. في رأيي (منحازة) ، يتعامل Cake مع المهام بشكل أفضل. أصبحت الحاجة إلى نموذج الاعتماد على المهمة واضحة عندما بدأنا في استخدام مخازن المؤسسات البروتوكول في مشروعنا مع لين. كانت البروتوبوف متطلبات مسبقة لجميع مهامنا ، ومع ذلك فإن تجميعها بطيئة حقًا. لدينا أيضًا الكثير من المهام المعتمدة ، لذلك كان أي بناء مؤلم. أنا أيضًا لا أحب متطلبات مساحة الاسم المنفصلة ، وبالتالي ملف SRC إضافي ، لكل مهمة أقوم بإنشائها. المطورين ينبغي إنشاء الكثير من المهام ، نهج لين يشجع هذا عن طريق إنشاء الكثير من الاحتكاك. مع الكعكة ، يمكنك فقط استخدام الماكرو deftask داخل project.clj.

لا يزال الكعك صغيرًا ، وعملًا مستمرًا ، لكنه مشروع نشط للغاية.

كما 2011-11-15 ، الإعلان عندمج الكعك ولين

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