21

最後の数日間、Clojure と ClojureScript のclojure.specをさらに掘り下げました。

今までは、spec を特定の形式のデータに依存するパブリック関数内:preおよびパブリック関数内でガードとして使用することが最も便利だと思いました。:post

(defn person-name [person]
  {:pre [(s/valid? ::person person)]
   :post [(s/valid? string? %)]}
  (str (::first-name person) " " (::last-name person)))

そのアプローチの問題は、仕様を正確に満たしていないものjava.lang.AssertionError: Assert failed: (s/valid? ::person person)についての情報なしで取得することです。

またはガードでより良いエラーメッセージを取得する方法を知っている人はいますか?:pre:post

conformとについては知っていますが、それらやガードexplain*には役に立ちません。:pre:post

4

4 に答える 4

6

spec/instrument前後の条件ではなく、関数の入力と出力を検証するために使用するという考え方だと思います。

このブログ投稿の下部に良い例があります: http://gigasquidsoftware.com/blog/2016/05/29/one-fish-spec-fish/ . 簡単な要約: :args キーと :ret キーを使用して入力値と戻り値の両方を含む関数の仕様を定義し (したがって、前条件と後条件の両方を置き換える)、それをインストルメント化すると、次の場合spec/fdefと同様の出力が得られますexplain仕様を満たしていません。

そのリンクから派生した最小限の例:

(spec/fdef your-func
    :args even?
    :ret  string?)


(spec/instrument #'your-func)

これは、関数が整数の引数を持つという事前条件と、文字列を返すという事後条件を設定することと同じです。あなたが探しているのと同じように、はるかに有用なエラーが得られることを除いて。

詳細については、公式ガイド: https://clojure.org/guides/spec ---「Spec'ing functions」という見出しの下を参照してください。

于 2016-06-18T03:02:44.830 に答える