ocaml printf function: skip formatting entirely if some condition holds

三世轮回 提交于 2019-12-01 10:50:35

The continuation functions such as Printf.kfprintf are provided specifically to allow format wrappers such as this. It looks something like this:

open Printf

type log_level = Error | Warn | Info

let ord = function Error -> 50 | Warn  -> 40 | Info  -> 30

let string_of_lvl = function
  | Error -> "error"
  | Warn -> "warn"
  | Info -> "info"

let current_level = ref (ord Warn)

let printf_with_info name lvl =
  kfprintf fprintf stdout "[<%s>] <%s>: " name (string_of_lvl lvl)

let logf name lvl =
  if ord lvl >= !current_level then match lvl with
   | Error | Warn -> printf
   | Info -> printf_with_info name lvl
  else
    ifprintf stdout

This seems to get me some of the way:

let logf name lvl =
    if (ord lvl) >= !current_level then
        Printf.fprintf stdout
    else
        Printf.ifprintf stdout

I'm surprised, as I thought this might mean !current_level would be evaluated too early (at module load time or something). But changing the current_level at runtime does seem to work correctly. I guess currying isn't pure like in haskell (which makes sense, given the impurity above ;)).

But it restricts me to using the fprintf family. I'd prefer to use ksprintf, because I also want a formatter, which (depending on log level) may add information like:

`[<name>] <level>: <message>`

Perhaps I could achieve this by concatenating formats (using ^^), but I don't see how.

Whatever you do, calling any Printf.*printf funciton will parse the format string at runtime. This may change in 4.02. Or you can use some syntax extension for conditional printing.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!