Более читаемые сообщения с :pre и :post?

В clojure я использую :pre вот так

user=> (defn cannot-take-empty [x] {:pre [((complement empty?) x)]} 1)
#'user/cannot-take-empty
user=> (cannot-take-empty #{})
AssertionError Assert failed: ((complement empty?) x)  user/cannot-take-empty (NO_SOURCE_FILE:186)

Это замечательно, но не объясняет бизнес-причину, почему не имеет смысла передавать пустую коллекцию. (Или коллекция с более чем пятью элементами, или коллекция, в которой присутствуют два ключа, но нет другого, или какое-то другое правило дня.) Это может еще больше сбить пользователя с толку, если в предварительном условии используется частная функция.

Есть ли способ предоставить пользователю более полезную обратную связь, например сообщение об ошибке, при использовании :pre и :post?


person George Simms    schedule 06.06.2015    source источник
comment
взгляните на этот ответ. Это немного некрасиво, но должно работать.   -  person soulcheck    schedule 07.06.2015
comment
@soulcheck Я надеялся избежать явного генерирования исключений, это кажется скорее java-подобным.   -  person George Simms    schedule 07.06.2015
comment
вы всегда можете обернуть его в функцию/макрос (defn wrapper [c text] (if (not c) (throw (AssertionError. text)))), но да, нехорошо.   -  person soulcheck    schedule 07.06.2015


Ответы (1)


По-видимому, предварительные и последующие условия предназначены для случаев использования, когда сообщение о пунктах предоставляет разработчику достаточно информации, т. Е. Это не требует пояснений. Если вы хотите дать больше пояснений, идиоматично использовать assert.

Но вы можете злоупотреблять тем фактом, что всегда сообщается все состояние, например. так:

{:pre [(do "It can't be empty because of..."
           (seq x))]}

И он сообщит что-то вроде

AssertionError Ошибка подтверждения: (сделайте "Он не может быть пустым из-за..." (seq x))...

person Leon Grapenthin    schedule 06.06.2015