2016-11-14 6 views
3

Я использую Clojure для реализации (письменного) документа стандартов. В общем, я доволен тем, как Clojure позволяет мне писать код, который соответствует различным частям стандарта. С прицелом на будущее я экспериментирую с написанием для него clojure.spec. В документе они определяют различные структурированные элементы данных с именованными полями. Однако поля в разных структурах имеют одно и то же имя, например, «красная» структура имеет поле «значение», которое является строкой, но «синяя» структура имеет поле «значение», которое является целым числом. Как я могу справиться с этим, когда речь заходит о написании спецификаций?спецификации clojure для карт и их значения

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

official advice, как я понимаю, в том, что названные ключи должны иметь ту же семантику везде.

Как мне подойти к этому? Я мог бы назвать их «red-value» и «blue-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/def ::red (s/keys :req-un [:red/value ...])) 
(s/def ::blue (s/keys :req-un [:blue/value ...])) 

Вы могли бы подтвердить ценности, как:

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

Спасибо. Просто, чтобы проверить мое понимание - красный в ':: red' полностью не зависит от того, что находится в': red/value', не так ли? Также существует какой-либо способ использования именных карт здесь, например. '# :: red {: значение" hi "...}' –

+1

Re red - yes. Синтаксис карты пространства имен является просто синтаксисом, поэтому '# :: red {: value" hi "}' и '{:: red/value" hi "}' - это точно такие же данные. Под этим я имею в виду, вы можете использовать либо, не имеет значения, и это полностью ортогонально от того, соответствуют ли данные спецификации. –

 Смежные вопросы

  • Нет связанных вопросов^_^