Понимание вывода в Clojure с использованием swank / slime - PullRequest
6 голосов
/ 26 декабря 2010

Когда я запускаю код Clojure из реплик Swank в emacs, основной поток будет распечатывать сообщения, используя printf для реплики.Но если я запускаю агенты или явно создаю другие потоки, которые также печатают, иногда выходные данные не отображаются, а иногда отображаются в окне консоли, где я запускаю Swank.Мне бы очень хотелось понять, почему.

Редактировать: Благодаря ответу Даниэля ниже я теперь знаю, что другие потоки не имеют out , привязанного к выходу REPL.Этот код работает, потому что вы передаете из , откуда вы бежите.Однако моя новая проблема заключается в том, что этот код теперь блокируется для каждого потока, поэтому вместо параллельной работы он запускает каждый поток по одному, поэтому мне нужен более понятный метод вывода.

(defn sleeper-thread [out id t]
  "Sleep for time T ms"
  (binding [*out* out]
    (printf "%d sleeping for time %d\n" id t)
    (Thread/sleep t)
    (printf "%d slept\n" id)))

(defn test-threads [n out]
  (dotimes [x n]
    (.start (Thread. (#(sleeper-thread %1 %2 %3) out x (+ 2000 (rand-int 5000)))))))

Ответы [ 2 ]

1 голос
/ 26 декабря 2010

Причина в том, что в других потоках *out* не связан с потоком REPL.Попробуйте что-то вроде этого:

(let [repl-out *out*]
  (defn foo []
    (binding [*out* repl-out]
      ...)))

Теперь, при запуске foo из другого потока, *out* будет привязан к тому, что было, когда вы определили функцию (например, SLIME REPL), поэтому печать будетработать как положено.

Или, для тестирования:

(defmacro future-output [& body]
  `(let [out# *out*]
     (future
       (binding [*out* out#]
         ~@body))))

Примечание: Это не проверено, потому что у меня нет работающего Clojure / SLIME здесь, но этот код работал несколько месяцев назад.Могут быть различия в более новых версиях Clojure (1.3 Alpha 2):

  • путь к коду для использования vars теперь намного быстрее дляобщий случай, и вы должны явно попросить: динамическая привязка
0 голосов
/ 31 января 2011

Если вы боретесь с тем же использованием торта, там должен быть файл журнала с выводом в файле .cake / cake.log в корне вашего проекта (где живет project.clj).

...