Как определить настраиваемые принтеры исключений с помощью Janestreet Core? - PullRequest
0 голосов
/ 09 июня 2018

По умолчанию исключение Failure печатается следующим образом:

# print_endline (Printexc.to_string (Failure "uh\noh"));;
Failure("uh\noh")

Для улучшения читаемости мы хотим напечатать аргумент Failure как есть, потому что мы понимаем, что он должен быть читаемым человеком,В стандартной библиотеке OCaml мы инициализируем приложение следующим образом:

# Printexc.register_printer (function
  | Failure s -> Some ("Failure: " ^ s)
  | _ -> None
);;

Новое поведение Printexc.to_string будет:

# print_endline (Printexc.to_string (Failure "uh\noh"));;
Failure: uh
oh

Отлично.Теперь, если мы используем библиотеку core_kernel, сначала мы увидим, что печать исключения немного отличается, но не лучше для читателя-человека:

#require "core_kernel";;
# print_endline (Printexc.to_string (Failure "uh\noh"));;
(Failure  "uh\
         \noh")

Возможно, мы сможем переопределить это?Давайте попробуем.

# Printexc.register_printer (function
  | Failure s -> Some ("Failure: " ^ s)
  | _ -> None
);;
# print_endline (Printexc.to_string (Failure "uh\noh"));;
Failure: uh
oh

Это работает, но он не использует принтер, который является частью Core_kernel.Если мы его используем, мы все равно получим тот же нечитаемый результат:

# print_endline (Core_kernel.Exn.to_string (Failure "uh\noh"));;
(Failure  "uh\
         \noh")

И Core_kernel.Exn не предлагает функцию register_printer.Таким образом, похоже, что Core_kernel.Exn гарантирует, что мы не определяем настраиваемые принтеры исключений.Есть ли другой способ или мы просто не должны использовать Core_kernel.Exn, тогда, если мы хотим показать удобочитаемые сообщения об ошибках?

Редактировать: Для контекста, наша первоначальная проблема - красиво распечатать вложенные сообщения об ошибках.Например, мы хотели бы прочитать что-то вроде следующего:

Uncaught exception: Failure:
  Uncaught exception in subprocess 1234: Failure:
    something happened
    trace line 1
    trace line 2
  trace line 1
  trace line 2
  trace line 3

, где мы используем отступ для кавычек и экранирования, а не двойные кавычки и escape-последовательности обратной косой черты.

1 Ответ

0 голосов
/ 10 июня 2018

Base.Exn (для которого Core_kernel.Exn - псевдоним) печатает ошибки в виде удобочитаемых s-выражений, используя принтер и конвертеры Sexplib0.Можно добавить пользовательский конвертер sexp для исключений с Sexplib0.Exn_converter.add.

Однако, если вы не собираетесь печатать исключения в виде s-выражений, я действительно не вижу причин использовать принтер Base.Exn.

РЕДАКТИРОВАТЬ: поскольку проблема, кажется,При печати S-выражений одним из решений может быть использование Base.Exn.sexp_of, а затем подключение пользовательских принтеров S-выражений, которые не экранируют строки и не печатают скобки:

let pp_sep ppf () = Format.fprintf ppf "@ "
let pp_sexp ppf = function
  | Atom s -> Format.pp_print_string ppf s
  | List l ->
    Format.fprintf ppf "@[<v 2>  %a@]" 
      (Format.pp_print_list ~pp_sep pp_sexp) l

let to_string exn = Format.asprintf "%a" pp_sexp (Exn.sexp_of_t exn)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...