为什么这里不调用 mark stag 函数?
Why mark stag functions are not called here?
我试图理解 OCaml Format
模块和语义标签的以下行为。
我的代码:
let prepare_ppf ppf =
let original_stag_functions = Format.pp_get_formatter_stag_functions ppf () in
let original_mark_tags_state = Format.pp_get_mark_tags ppf () in
Format.pp_set_mark_tags ppf true;
Format.pp_set_print_tags ppf false;
Format.pp_set_formatter_stag_functions ppf {
mark_open_stag = (fun stag ->
print_endline "MARK-OPEN";
match stag with
| Format.String_tag s -> Printf.sprintf "<open:%s>" s
| _ -> "<UNKNOWN>"
);
mark_close_stag = (fun stag ->
print_endline "MARK-CLOSE";
match stag with
| Format.String_tag s -> Printf.sprintf "</close:%s>" s
| _ -> "</UNKNOWN>"
);
print_open_stag = (fun _ -> print_endline "PRINT-OPEN"; ());
print_close_stag = (fun _ -> print_endline "PRINT-CLOSE"; ());
};
print_endline "PREPARED";
if Format.pp_get_mark_tags ppf () then print_endline "MARK:true";
(fun ppf ->
print_endline "RESET";
Format.pp_set_mark_tags ppf original_mark_tags_state;
Format.pp_set_formatter_stag_functions ppf original_stag_functions;)
let fprintf ppf fmt =
let reset = prepare_ppf ppf in
Format.kfprintf reset ppf fmt
let printf fmt = fprintf Format.std_formatter fmt
如果我将其粘贴到:utop 2.8.0 版(使用 OCaml 4.12.0 版)
当我运行它时:
utop # printf "@{<bold>%s@}" "hello";;
PREPARED
MARK:true
RESET
<bold>hello</bold>- : unit = ()
为什么 mark_open_stag
和关闭函数没有被调用?
如果我将第 5 行更改为 Format.pp_set_print_tags ppf true;
,那么我会看到调用了 print_open_stag
和关闭函数。
这是标准输出格式化程序的缓冲和 utop 处理之间的交互。
可以通过
看到缓冲问题
printf "@{<bold>%s@}" "A very very very very very very very very very very very very very very very very very long hello world";;
打印出一半正确的结果
PREPARED
MARK:true
MARK-OPEN
<open:bold>A very very very very very very very very very very very very very very very very very long hello worldRESET
</bold>
更进一步,最后用
刷新标准输出
printf "@{<bold>%s@}@." "hello";;
产生正确的输出
PREPARED
MARK:true
MARK-OPEN
<open:bold>helloMARK-CLOSE
</close:bold>
RESET
问题是
printf "@{<bold>%s@}" "hello"
完全缓冲所有输入。
它是 utop 牵手 stdout 格式化程序,它通过尝试打印
来触发打印
- : unit = ()
这会产生
<bold>hello</bold>- : unit = ()
因为在打印时 utop
已将格式化程序配置重置为其默认值。
我试图理解 OCaml Format
模块和语义标签的以下行为。
我的代码:
let prepare_ppf ppf =
let original_stag_functions = Format.pp_get_formatter_stag_functions ppf () in
let original_mark_tags_state = Format.pp_get_mark_tags ppf () in
Format.pp_set_mark_tags ppf true;
Format.pp_set_print_tags ppf false;
Format.pp_set_formatter_stag_functions ppf {
mark_open_stag = (fun stag ->
print_endline "MARK-OPEN";
match stag with
| Format.String_tag s -> Printf.sprintf "<open:%s>" s
| _ -> "<UNKNOWN>"
);
mark_close_stag = (fun stag ->
print_endline "MARK-CLOSE";
match stag with
| Format.String_tag s -> Printf.sprintf "</close:%s>" s
| _ -> "</UNKNOWN>"
);
print_open_stag = (fun _ -> print_endline "PRINT-OPEN"; ());
print_close_stag = (fun _ -> print_endline "PRINT-CLOSE"; ());
};
print_endline "PREPARED";
if Format.pp_get_mark_tags ppf () then print_endline "MARK:true";
(fun ppf ->
print_endline "RESET";
Format.pp_set_mark_tags ppf original_mark_tags_state;
Format.pp_set_formatter_stag_functions ppf original_stag_functions;)
let fprintf ppf fmt =
let reset = prepare_ppf ppf in
Format.kfprintf reset ppf fmt
let printf fmt = fprintf Format.std_formatter fmt
如果我将其粘贴到:utop 2.8.0 版(使用 OCaml 4.12.0 版)
当我运行它时:
utop # printf "@{<bold>%s@}" "hello";;
PREPARED
MARK:true
RESET
<bold>hello</bold>- : unit = ()
为什么 mark_open_stag
和关闭函数没有被调用?
如果我将第 5 行更改为 Format.pp_set_print_tags ppf true;
,那么我会看到调用了 print_open_stag
和关闭函数。
这是标准输出格式化程序的缓冲和 utop 处理之间的交互。
可以通过
看到缓冲问题printf "@{<bold>%s@}" "A very very very very very very very very very very very very very very very very very long hello world";;
打印出一半正确的结果
PREPARED
MARK:true
MARK-OPEN
<open:bold>A very very very very very very very very very very very very very very very very very long hello worldRESET
</bold>
更进一步,最后用
刷新标准输出printf "@{<bold>%s@}@." "hello";;
产生正确的输出
PREPARED
MARK:true
MARK-OPEN
<open:bold>helloMARK-CLOSE
</close:bold>
RESET
问题是
printf "@{<bold>%s@}" "hello"
完全缓冲所有输入。 它是 utop 牵手 stdout 格式化程序,它通过尝试打印
来触发打印- : unit = ()
这会产生
<bold>hello</bold>- : unit = ()
因为在打印时 utop
已将格式化程序配置重置为其默认值。