8

emacs cider-repl で次のコードを評価しようとすると、予想どおり nil が返されますが、repl バッファーまたはコンソールで出力が行われません。この印刷物を意図したとおりに出力するにはどうすればよいですか?

(dotimes [i 5]                                                                                                                                        
  (.start                                                                                                                                             
   (Thread.                                                                                                                                           
    (fn []                                                                                                                                             
      (Thread/sleep (rand 500))                                                                                                                       
      (println (format "Finished %d on %s" i (Thread/currentThread)))))))
;=> nil

ただし、これは正常に機能します。

(println (format "Finished 1 on %s" (Thread/currentThread)))
;=> Finished 1 on Thread[nREPL-worker-18,5,main]
----------- mini-buffer -----------------
nil
4

4 に答える 4

11

の動作は、その出力ストリームとしてprintln呼び出される動的にバインドされた var を使用することです。*out*emacs*out*は repl バッファーで評価されたコードの repl バッファーに移動するように動的にバインドしますが、スレッドを作成すると、そのスレッド*out*は のルート バインディングを取得し*out*ます。サイダーの場合は repl バッファーにはなりません。

を使用してreplを開始した場合、バッファリストを見ると、ルートバインディングの出力を含むcider-jack-inような名前のバッファがあるはずです。コードを実行した後の私の内容は次のとおりです。*nrepl-server**out*

nREPL server started on port 52034 on host 127.0.0.1 - nrepl://127.0.0.1:52034
Finished 1 on Thread[Thread-9,5,main]
Finished 0 on Thread[Thread-8,5,main]
Finished 2 on Thread[Thread-10,5,main]
Finished 3 on Thread[Thread-11,5,main]
Finished 4 on Thread[Thread-12,5,main]

を使用しなかった場合cider-jack-in、出力は nrepl プロセスを開始した端末に出力されます。

于 2014-11-04T20:10:36.683 に答える
10

*out*printlnおよび同様の関数からの出力先を決定する動的変数です。cider で表示するために何かを emacs に送り返す原因となる場所にスレッドバインドされています。新しいスレッドを開始すると、そのバインディングは存在せず、出力は別の場所に移動します (おそらく、バックグラウンドで開始された nrepl サーバー emacs/leiningen の stdout に出力されます)。

これにはいくつかの方法で対処できます。親スレッドからの値を取得し、*out*それをクロージャーで子スレッドに渡し、再バインド*out*することができます。

(let [out *out*] 
  (.start (Thread. (fn [] 
                     (binding [*out* out]
                        (println "test"))))))

またはfuture、自分でスレッドを開始する代わりに a を使用することもできます。Clojure は、関連するスレッド ローカル バインディングを、将来開始される新しいスレッドに自動的に伝達します。

于 2014-11-04T20:11:10.400 に答える
8

repl で次の式を実行すると、すべての出力が repl になります。

(alter-var-root #'*out* (constantly *out*))

元の答え:

https://groups.google.com/d/msg/cider-emacs/bIVBvRnGO-U/nDszDbGoVzgJ

于 2014-11-21T07:26:20.453 に答える
0

Figwheel を使用している場合、リング ハンドラーで prn/println を実行すると (実際には上記の Threads の例に似ています)、Fighweel 自体によって飲み込まれる可能性があります。プロジェクトの project.clj を確認します (:figwheel マップ内のキー :server-logfile を探します)。ここで、repl に移動するかログファイルに移動するかを制御できます。これは figwheel を使用している場合にのみ適用されることに注意してください。それ以外の場合は、もちろん REPL への出力は正常に機能します。

詳細については、この質問に対する私の回答を参照してください: Compojure サーバーの印刷ステートメントを figwheel ターミナルに出力しますか?

于 2017-06-27T15:57:55.640 に答える