2016-06-30 10 views
8

私はclojure.spec guideに従っています。私は、clojure.spec/keysを使用する際に必須属性とオプション属性を宣言することが可能であると理解しています。clojure.specで禁止されているキー

私はオプションの意味を理解していません。私にとって:optは何もしません。

(s/valid? (s/keys :req [:my/a]) {:my/a 1 :my/b 2}) ;=> true 

(s/valid? (s/keys :req [:my/a] :opt []) {:my/a 1 :my/b 2}) ;=> true 

このガイドでは、「オプションの属性が役立つ場合がありますが、後で説明しますが、説明を見つけることができません」と説明しています。禁止キーを宣言できますか?または、何とかreqと:opt?のキーと等しい有効なキーのセットを宣言しますか?

答えて

8

は、これは非常に良い質問です、そしてclojure.spec APIは(許可され、短いとあっけなく)答え与える:

:オプトキーは、ドキュメントとしての役割を果たすと は発電機で使用することができます。

このメソッドを使用して余分なものが含まれているとマップを無効にすることはできません(これは "禁止されています"ということです)。しかし、あなたは確認するために、この仕様を使用することができます::悪いキーが存在しない:

(s/def ::r (s/and (s/keys :req [::reqd1 ::reqd2]) #(= (count %) 2))) 
(s/valid? ::r {::reqd1 "abc" ::reqd2 "xyz"})    ; => true 
(s/valid? ::r {::reqd1 "abc" ::reqd2 "xyz" ::extra 123}) ; => false 

(s/def ::m (s/and (s/keys :req [::a]) #(not (contains? % ::bad-key)))) 
(s/valid? ::m {::a "required!"})      ; => true 
(s/valid? ::m {::a "required!" ::b "optional!"})  ; => true 
(s/valid? ::m {::a "required!" ::bad-key "no good!"}) ; => false 

あなたはこの仕様を利用して希望通りのセットにキーの数が制限される可能性が

しかし、このIMOを処理する最良の方法は、あなたが気にしない重要な存在が存在することを単に無視することです。

仕様が成熟したらうまくいけば、これらの素晴らしいものが追加されることを願っています。または、おそらく彼らはすでにそこにいる(それは急速に変化している)と私は単にそれについて知らない。これはクロージャーの非常に新しいコンセプトなので、私たちの多くはそれについて学ぶことがたくさんあります。

更新日 - 2016年12月 私はちょうどそれを書いてからこの6ヶ月を再訪したいと思っていました。あなたが気にしないキーを無視することについての私の最初のコメントは、行くのが好ましい方法です。実際に、私は2週間前に出席したclojure/conjカンファレンスで、Richの基調講演では、機能レベルからアプリケーションレベルまでのあらゆるレベルのソフトウェアにおけるバージョン管理という概念に具体的に取り組んでいました。彼は具体的に言えば、話の中の鍵を不許可にするというこの考え方は、on youtubeであると言えます。彼は、必要なキーだけを指定できるように意図的に設計されていると言います。キーを無効にすることは、本当に良い目的を果たすものではありません。

:optキーについては、私は、元の答えはまだかなりよく立ち上がると思う - それはドキュメントだし、事実上、それはこれらのオプションで指定したキーを生成することができます。

(s/def ::name #{"Bob" "Josh" "Mary" "Susan"}) 
(s/def ::height-inches (s/int-in 48 90)) 
(s/def ::person (s/keys :req-un [::name] :opt-un [::height-inches])) 

(map first (s/exercise ::person)) 

; some generated data have :height-inches, some do not 
({:name "Susan"} 
{:name "Mary", :height-inches 48} 
{:name "Bob", :height-inches 49} 
{:name "Josh"} 
+0

"キーを無効にすることは実際には役に立たず、慎重に行う必要があります。うーん。私は文脈でそれを聞くために話を見なければならないが、パスワードフィールドが関数から漏れないことを確認することはどうだろうか?私は、明示的なキーの他に何か他の方法でそれを漏らしていないことを本当に保証できないことを指摘していますが、明白なものをチェックすることは良い目的を持っていないと言って少し誇張されているようですね。 – neverfox

+0

私は話を聞いた。私は、あなたができないものではなく、あなたができることについてスペックがあることを知っています。しかし、彼はそれを無視することが好ましい方法だとは正確には言いませんでした。彼はそれが2つの好ましい方法の1つであり、もう1つは「政策を持っている」と述べた。私が正しく理解すれば、私は成長を阻止しないためにいくつかのことをすることができます:1)あなたが表示する方法を使用してキーを許可しなかった "ちょっと無視する"永遠に使用する、または後でドロップする、2)独立したチェッカーを書く。彼は実際に私の場合にも対処しました。多分選択キーを使うべきでしょう。 – neverfox

-3

オプションのキーについてのポイントですは、マップに表示されている場合に検証されます

+1

これは間違いです。値は無関係に検証されます。 –

+0

キーが必須でもオプションでもない場合、値はまったく検証されません。私は必要なキーのために値が妥当性検査されていないことを意味しませんでした – DanLebrero

+1

"さらに、* all *名前空間修飾キーの値は登録された仕様で (そしておそらくは非構造化) ( 's/keys'のDocstr) –

関連する問題