2016-11-14 3 views
3

私はClojureを使用して(書かれた)標準文書を実装しています。一般的に私は、Clojureが標準のさまざまな部分と並ぶコードを書くことを可能にする方法に満足しています。私は未来を見据えて、clojure.specを書きました。文書では、名前付きフィールドを持つさまざまな構造化データ要素を定義しています。しかし、異なる構造のフィールドには同じ名前があります。たとえば、 'red'構造体には文字列の 'value'フィールドがありますが、 'blue'構造体には整数の 'value'フィールドがあります。スペックを書く場合、どうすれば対応できますか? official adviceマップとその値のクロージャの仕様

(s/def ::value ???) 
(s/def ::red (s/keys :req [::value ...])) 
(s/def ::blue (s/keys :req [::value ...])) 

は、私はそれを理解し、名前の鍵はどこでも同じ意味を持つべきであるということです。

私はこれにどのようにアプローチすればよいですか?私はそれらを「赤価値」と「青価値」と呼ぶことができますが、これによりコードと標準との対応があまり明確になりません。すべての構造を独自の名前空間に入れることができますか?

答えて

3

あなたの例では、すべてのスペック名に現在の名前空間を使用していますが、名前空間を利用して名前の曖昧さを解消する必要があります。

(s/def ::red (s/keys :req [:red/value ...])) 
(s/def ::blue (s/keys :req [:blue/value ...])) 

あなたが好きなマップでこれらの仕様を使用することができます:それはあなたがで動作するように持っているものかどう

さらに
(s/valid? ::red {:red/value "foo"}) 
(s/valid? ::blue {:blue/value 100}) 

s/keysは、修飾されていない属性名に名前のスペックをリンクする:req-unオプションをサポートしています。

(s/valid? ::red {:value "foo"}) 
(s/valid? ::blue {:value 100}) 
+0

ありがとう:

(s/def ::red (s/keys :req-un [:red/value ...])) (s/def ::blue (s/keys :req-un [:blue/value ...])) 

あなたのような値で検証することができます。私の理解を確認するために、 ':: red'の赤は':red/value'のものとは完全に独立していますか?また、ここで名前空間マップを使用する方法もあります。 '#:: red {:value" hi "...}' –

+1

赤い - はい。名前空間マップの構文は構文だけなので、 '#:: red {:value" hi "}'と '{:: red/value" hi "}'はまったく同じデータです。つまり、どちらを使うこともできますが、問題はありません。データが仕様に準拠しているかどうかは完全に直交しています。 –