47

私は Clojure を初めて使用し、アプリケーションの構築を試し始めています。

これまでのところ、Clojure プログラムのコンパイルに関するチュートリアルについて私が見たものはすべて、対話性に関係しています。たとえば、「REPL をロードして (load-file "this-or-that") と入力して実行します。これは問題ありませんが、十分ではありません。

私は C や Delphi のような言語の編集、コンパイル、実行のイディオムに慣れているため、本能的に編集を行い、「Mx コンパイル」を押します。

問題は、「make」と同等であると私が理解している「lein uberjar」は、hello world であっても実行が非常に遅いことです。だから私は、この「インタラクティブな開発」がどのように機能するかを理解し、uberjar をクイックメイクのように使用するのをやめ、1 日の終わりにのみ保存する必要があります。

(lein uberjar を使用して) ビルド中に気付いたもう 1 つのことは、私が取り組んでいる小さな GUI アプリが、コンパイル中に実行されているかのように、コンパイル プロセスでフレームをポップアップすることです。私には少し直感に反するように思えます。私が思っていたほど「作る」とは似ていません。

私は物事を開発する Lisp の方法が REPL でインタラクティブに機能していることを知っています。私はそれを変えようとはしていません: 私はこの生き方に適応したいと思っています。残念ながら、その方法に関するドキュメントの形式はほとんど見たことがありません。たとえば、マシンの現在の状態をリセットする方法。ある種のリセットを行うことなく、個々のスニペットをオンザフライでコンパイルし続けるのは、ちょっと面倒に思えます。

私が見た Clojure (および Lisp) に関するほとんどのチュートリアルは、一般的に REPL のハッキングに焦点を当てているようです。アプリケーションの展開に関するベスト プラクティスは、私にとって謎のままです。私のユーザーはただのユーザーになります。ファイルを REPL にロードする開発者にはなりません。

そこで私の質問です。デプロイを含む Clojure アプリケーションの構築プロセス全体に関する適切な情報やチュートリアルのリソースはありますか?

(注: すべての前提条件 (Emacs、Slime、Leiningen など) をインストールして動作させているので、それについての質問ではありません)。

4

2 に答える 2

26

いくつかの簡単なヒント、そしていくつかのリンク:

lein uberjar開発中は使用しないでください。を好むlein jar。違いはlein uberjar、生成されたすべての依存関係jar(Clojure自体を含む)を配置するため、単一のjarが完全に自己完結型のパッケージであり、アプリが内部に含まれていることです。lein jarあなた自身のコードをjarするだけです。このuberjarアプローチにはデプロイに明らかなメリットがありますが、開発には、アプリの実行時に適切なクラスパスを使用するだけで、uberjarの準備に必要な時間を節約できます。テスト実行のためにクラスパスを手動で管理したくない場合は、lein runプラグインを確認してください。

また、ほとんどの場合、コードの大部分は実際にはAOTコンパイルされるべきではありません。一部のJava相互運用シナリオではAOTが必要ですが、ほとんどの場合、起動速度がわずかに向上し、Clojureのさまざまなリリースとのバイナリ互換性に関する厄介な問題が発生します。後者の問題は、uberjar-edスタンドアロンアプリの種類のプロジェクトには関係ないと思いますが、可能であれば、少なくともライブラリコードはJIT-edのままにしておく必要があります。Leiningenを使用すると、フォームに:namespaces句を入れて、コンパイルする名前空間を決定できます。省略したものはすべて、現在デフォルトでJITされます。Leiningenの古いバージョンは、デフォルトですべてをコンパイルするために使用されていました。これは、実際にアップグレードするのに十分な理由です。defprojectproject.clj

コンパイル中にポップアウトするウィンドウについては、マクロ展開時にウィンドウアウトポップコードを実行しているか、関数定義または同様の構造の外部で実行していると思います。((println "Foo!")トップレベルのようなものです。)とにかく、コードをスクリプトとして実行することを計画しているのでない限り、それはあなたがすべきではないことだと思います。この問題を回避するには、副作用のあるコードを関数定義にラップし、の:main句を使用してアプリケーションへのエントリポイントを提供しますproject.clj。(と言うと:main foo、名前空間の-main関数がfooアプリへのエントリポイントとして使用されます。とにかく、これがデフォルトであり、少なくとも上記lein runの名前はハードコードされているようです。lein自体についてはわかりません。)

REPLの状態をリセットする場合は、再起動するだけです。SLIMEを使用すると、Mx Slime-restart-inferior-lispは、Emacsセッションの他のすべての状態を維持しながらそれを実行します。

ClojureGoogleグループに関する次のディスカッションも参照してください。

  1. システム管理用のClojure
  2. パッケージング用のclojureの準備(以前は:Re:システム管理用のClojure)
  3. Leiningen、Clojure、およびライブラリ:何が欠けていますか?
于 2010-03-06T08:03:00.387 に答える
13

いいえ、REPL で関数を入力しません。

いつものように、ソース ファイルを編集します。Lisp の利点は、システムを同時にバックグラウンドで実行できることです。そのため、ソース ファイルから個々の関数をコンパイルして、実行中のシステムに配置したり、実行中のシステムに置き換えたりすることができます。

Slime を使用する場合C-c C-cは、ソース ファイルを押して、その時点で関数をコンパイルおよびロードします。その後、REPL に切り替えてテストと探索を行うことができますが、ソースとして保持したいものはすべてソース ファイルに入れます。

チュートリアルは通常、REPL に入力することから始まります。これは、設定する必要があるものがあまりないためですが、本格的な開発では、実行中のシステムとソース ファイルの管理が統合されます。


例として、私の通常のワークフロー (Common Lisp を使用していますが、Clojure も同様です) は次のようになります。

  • Emacsを起動
  • M-x slimeLispシステムであるSlimeを起動し、Swankを介して2つを接続します
  • ,(コマンド)load-system foo現在のプロジェクトをロードします (必要な場合のみコンパイルします)。
  • C-x bソースバッファに切り替える
  • C-c ~ソースディレクトリを現在のディレクトリにし、ソースパッケージをREPLの現在のパッケージにします

これで、システムがバックグラウンドで実行されるようにセットアップされました。作業は次のとおりです。

  • 関数またはクラスの定義を変更または追加する
  • C-c C-cコンパイルしてイメージにロードする
  • REPL に切り替え、テストする
  • デバッグ

一度にすべてをコンパイルすることはなく、個々の定義だけをコンパイルするため、コンパイルの大幅な一時停止はありません。

于 2010-03-06T11:58:04.157 に答える