2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

flush in Clojure print and println

2
Last updated at Posted at 2015-02-28

Compojureを使っていて標準出力にログが出力されないことがあった。はじめは以下のように書いていた。

(ns hello-world.core
  (:require [compojure.core :refer :all]
            [compojure.route :as route]))

(defroutes app
  (GET "/" [] "<h1>Hello World</h1>")
  (GET "/debug" []
    (print "debug") ;; これが表示されない :(
    "This is debug")
  (route/not-found "<h1>Page not found</h1>"))

ところがこれは出力されなかった。少し調べてみてこの記事を見つけた。どうやらflushの問題らしい。printは内部的にはflushをしていないのでこれを呼ぶだけだと直ちに標準出力からdebugログが見られるわけじゃない。

printlnで書き換えてみるとうまくいった。


(defroutes app
  (GET "/debug" []
    (println "debug")
    "This is debug")

実際ソースを見てみるとflushしていることがわかる。

user=> (source print)
(defn print
  "Prints the object(s) to the output stream that is the current value
  of *out*.  print and println produce output for human consumption."
  {:added "1.0"
   :static true}
  [& more]
    (binding [*print-readably* nil]
      (apply pr more)))

printは内部的にprを使ってる。

user=> (source println)
(defn println
  "Same as print followed by (newline)"
  {:added "1.0"
   :static true}
  [& more]
    (binding [*print-readably* nil]
      (apply prn more)))

printlnprnを使ってる。

prprn関数を見比べてみる。


user=> (source pr)
(defn pr
  "Prints the object(s) to the output stream that is the current value
  of *out*.  Prints the object(s), separated by spaces if there is
  more than one.  By default, pr and prn print in a way that objects
  can be read by the reader"
  {:dynamic true
   :added "1.0"}
  ([] nil)
  ([x]
     (pr-on x *out*))
  ([x & more]
   (pr x)
   (. *out* (append \space)) ;; とくにflushを呼んでいるわけではなさそう
   (if-let [nmore (next more)]
     (recur (first more) nmore)
     (apply pr more))))

user=> (source prn)
(defn prn
  "Same as pr followed by (newline). Observes *flush-on-newline*"
  {:added "1.0"
   :static true}
  [& more]
    (apply pr more) ;; 実際の表示にはprを使ってる
    (newline)
    (when *flush-on-newline*
      (flush)))  ;; 確かにここでflushをしている

debug用だったらprintlnをいつも使うようにしておいた方が困惑しなさそう。

参照:
http://grokbase.com/t/gg/compojure/119ppmeay6/where-are-the-message-produced-by-printf-in-a-compojure-project

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?