2012-01-16 18 views
4

SBCLの# 'save-lisp-and-dieを使用してApp1というサーバーアプリケーションを作成すると、うまくいきます。今度は、関数# 'func1をApp1を停止せずに新しいバージョンに置き換えたいと考えています。 Common Lispでどうすればいいですか?Common Lispで実行中の関数を置き換えるには?

ご迷惑をおかけして申し訳ございません。

+0

実行中のLispプログラムで関数を置き換えることを参照するか、呼び出されている間に関数を置き換えることを頼りにしていますか(たとえば、長いループで)? –

+0

私は実行中のLispプログラムで、実行されているかもしれないし、ないかもしれない関数を置き換えることを意味します。 –

答えて

3

新しい関数定義を読み込む必要があります。新しい機能がすぐに利用可能になります。コードは新しくロードされた関数を呼び出します。

新しい関数定義は、多くの方法でロードすることができる。 :file.lispfile.fasl

  • (eval (defun ...))
  • のソースコードにコンパイルされた関数

  • (load "file.fasl")のソースコードがある

    • (load (compile-file "file.lisp"))コースには、例外と合併症があります:

      • これは、以前の機能の実行中の呼び出しを置き換えません。たとえば、無限のイベントループをこのように変更することはできません。何らかの種類の停止と新しい関数の呼び出しをサポートする必要があります。しかし、そのような長時間実行する機能はまれです。ループの代わりに再帰を使用することで回避できます(ただし、すべてのコンパイラがテールコールの最適化を行うわけではありません)。
      • 関数のポインタをどこかに持っていたら(たとえば、(function FOO)によって、FOOが関数の名前である)、古い値が保持されます。これを避けるには、関数ポインタの代わりにシンボルを使用してください(シンボルはfuncallです)。
      • 関数のコードは、ガベージコレクションの対象です。関数の古いバージョンへの参照を捨てないように注意する必要があります。また、機能が必要ない場合は、fmakunboundのシンボルを忘れないようにしてください。
      • コンパイル時に関数が使用された場合は、影響を受けるコードもすべて再ロードする必要があります。
      • コンパイル時に高レベルの最適化(デフォルトではありません)があった場合、 CLHSは、関数を再定義することが«定義されていない動作»になった場合を判別します。

      実際には、コードリロードはほとんどのCommon Lisp実装でうまくいきます。

  • 10

    私は個人的にSWANK(SLIMEのサーバー部分)が動作しているので、Emacs + SLIMEを使っていつでもイメージに接続して、必要なものを再定義できます。

    (ql:quickload "swank") 
    (swank:start-server :port 1234) ;; listen for SLIME connections on port 1234 
    

    次にEmacsでは、M-x slime-connectを入力し、プロンプトに従います。

    何らかの理由でこれを実行したくない場合は、実装で特定のものが提供されることがあります。

    +0

    リリースされた画像にスワンクを含める必要がありますか? –

    +4

    また、プログラムの実行中に機能を置き換えてロードする新しいパッチファイル用のディレクトリを見ることもできます。 – sbenitezb

    +1

    リリース時の画像にスワンクを入れても問題は発生しません。実際には生産時にホットパッチできるようにしたいと思っています。ポートが何とか安全であることを確認してください。 –

    関連する問題