質問
ケーキとライインニンの違いは何ですか?
解決
この答えは、おそらくStackoverflowのLeiningenのリファレンスとして関心を持ち続けているため、2014年に更新するために大幅に編集されています。
LeiningenとCakeは2011年に融合しました。Leiningen(バージョン2)は、事実上のClojure Automationツールです。
レインニンンClojureのビルドツールと依存関係マネージャーです。これには、適切に構成されたClassPathおよびMavenリポジトリおよび/またはコミュニティベースのコミュニティから自動化された方法で取得されたすべてのJavaおよびClojure依存関係を持つインタラクティブなREPLを設定する機能が含まれます。 クロイジャー.
CakeはLeiningenに非常によく似ていました(当時同じプロジェクトを使用するのと同じです)が、背景に永続的なJVMを維持することで、多くのスタートアップのオーバーヘッドを避けようとしました。これはより反応が良かったが、反復的なREPLベースの開発の典型的なコースで、永続的なプロセス(古い関数定義など)に蓄積された状態(古い関数定義など)のためにバグの利便性が取引された。これは悪い掘り出し物であることが判明しました。
Leiningenとの経験と、より速いスタートアップの時間に対する継続的な欲求は、物事を高速化するための多くの推奨事項とアプローチにつながりました。 https://github.com/technomancy/leiningen/wiki/faster
他のヒント
主な違いは、タスクの実装方法です。
Cakeのアプローチは、「機能が定義された後に機能を拡張するのが難しいので、機能を使用するのではなく、タスクの新しいメカニズムを発明しましょう」。
Leiningenのアプローチは、「機能が定義された後に機能を拡張するのは難しいので、これを簡単に行う方法を作る必要があります。そのため、タスクに関数を使用し、タスクではないものを拡張できるようになります」タスクを使用して、関数のすべてのコンポジャブル性の利点を適用できます。
アレックスが述べたように、最も印象的な違いはコマンドラインからの速度です。 Cakeは永続的なJVMを使用するため、プロジェクト内で初めてタスクを実行したときにJVMスタートアップオーバーヘッドにのみ遭遇します。 Emacs + Slime + Clojure-Test-Modeを使用していない場合、これは巨大なタイムセーバーになる可能性があります。たとえば、私のプロジェクトの1つでのかなり大きなテストのセットは、ケーキで0.3秒で実行されます。
パフォーマンスとは別に、ケーキの背後にあるコアアイデアは依存関係タスクモデルです。各タスクは、依存関係グラフのすべての推移的前提条件を考慮して、特定のビルドで1回のみ実行されます。これが例です Rakeに関するMartin Fowlerの記事 Cake Syntaxでは、Project.cljに直接入ります。
(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...")
...)
Leiningenで同じことを行うには、最初にプロジェクトにLeiningenディレクトリを作成する必要があります。Code_gen.clj、compile.clj、data_load.clj、およびmy_test.cljの4つのファイル。
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/leiningen/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...
しかし、データロードと私のコンパイルの両方がコードギンに依存するため、実際のouputは...
generating code...
compiling...
generating code...
loading test data...
running tests...
Code-Genが複数回実行されないようにするには、コードGenをメモ化する必要があります。
(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...
それが私たちが望むものです。
ビルドがビルドごとに1回しか実行されない場合、ビルドはよりシンプルで効率的です。そのため、ケーキビルドでデフォルトの動作にしました。哲学は数十年前のものであり、ビルドツールの系統によって共有されています。それでも機能を使用できますが、繰り返し呼び出すことができ、常にClojureの完全な力を自由に使用できます。
Leinは、タスクとして単純な関数を提供するだけですが、SRCに独自の名前空間が必要であるという制約が追加されています。タスクがそれに依存している場合、それは別の名前空間になり、その中で他の名前を使用/要求する必要があります ns
大きい。ケーキビルドは、比較してはるかにきちんとした簡潔に見えます。
もう1つの重要な違いは、タスクの追加方法です。追加したかったとしましょう my-test
ケーキ/レインの組み込みの前提条件として jar
タスク。ケーキでは、を使用できます deftask
マクロタスクのフォームと依存関係に追加します。
(deftask jar #{my-test})
LeinはRobert Hookeを使用してタスクに追加します。それは本当にクールなライブラリであり、みんなのお気に入りの自然哲学者にちなんで名付けられましたが、その簡潔さにはマクロが必要です deftask
.
(add-hook #'leiningen.jar/jar (fn [f & args]
(my-test)
(apply f args)))
ケーキにはグローバルプロジェクトの概念もあります。 Swankなどのユーザー固有の開発依存関係を追加できます。 ~/.cake/project.clj
そして、あなたのすべてのプロジェクトにそれを持っています。グローバルプロジェクトは、実験用のプロジェクト以外のREPLを開始するためにも使用されます。 Leinは、ユーザーごとの構成をサポートすることにより、同様の機能を実装します ~/.lein/init.clj
, 、およびグローバルプラグイン ~/.lein/plugins
. 。一般に、Leinは現在、ケーキよりもはるかに豊富なプラグインエコシステムを持っていますが、ケーキには箱から出したタスク(戦争、展開、Javaコンピレーション、ネイティブ依存関係、Clojars、Swank)が含まれています。 CLJRはチェックアウトする価値があるかもしれません。基本的にはパッケージマネージャーを持つグローバルプロジェクトですが、ビルド機能はありません(ただし、経験はありません)。
技術が指摘したように、実際の非報告の違いはタスクの債務です。私の(偏った)意見では、ケーキはタスクをはるかに優れたものに処理します。レインとのプロジェクトでプロトコルバッファーの使用を開始したとき、タスク依存性モデルの必要性が明らかになりました。プロトブフはすべてのタスクの前提条件でしたが、それらをコンパイルするのは本当に遅いです。また、多数の相互依存タスクがあるため、どんなビルドでも苦痛でした。また、私が作成するすべてのタスクに対して、個別の名前空間の要件、したがって追加のSRCファイルが好きではありません。開発者 したほうがいい 多くのタスクを作成し、レインのアプローチは、あまりにも多くの摩擦を生み出すことでこれを思いとどまらせます。ケーキを使用すると、Project.clj内でDeftask Macroを使用できます。
ケーキはまだ若く、進行中の作業ですが、非常に活発なプロジェクトです。
2011-11-15、の発表ケーキとレインマージ