Clojure Spec обращается к данным в иерархической спецификации

Если у вас есть набор спецификаций, которые используются для проверки иерархического набора данных, скажем, файл yaml. Можно ли в одной из дочерних спецификаций ссылаться на данные, которые встречаются в дереве раньше?


person mmer    schedule 11.10.2017    source источник
comment
У вас есть конкретный пример? Вообще говоря, ваши внутренние/вложенные спецификации не будут получать наследственные данные, но, возможно, вы могли бы решить проблему с помощью внешней спецификации.   -  person Taylor Wood    schedule 11.10.2017
comment
Я хочу проверить некоторый yaml, представляющий сложную структуру данных. Точка проверки, которую я хочу доказать, это когда одна часть структуры ссылается на другую часть той же самой структуры, но я хочу доказать, что эта часть действительно существует. Это означает, что вы собираетесь применить предикат в точке ссылки и вернуться вверх по дереву yaml, а затем вернуться к точке элемента, на который указывает ссылка. Для этого мне нужно иметь возможность получить родителя спецификации, которая проверяет ссылку.   -  person mmer    schedule 11.10.2017
comment
Похоже, вы хотите, чтобы мы написали для вас код. Хотя многие пользователи готовы создавать код для кодера, попавшего в беду, обычно они помогают только тогда, когда автор уже пытался решить проблему самостоятельно. Хороший способ продемонстрировать эти усилия — включить код, который вы уже написали, примеры входных данных (если они есть), ожидаемые выходные данные и выходные данные, которые вы фактически получаете (консольный вывод, трассировка и т. д.). Чем больше деталей вы предоставите, тем больше ответов вы, вероятно, получите. Ознакомьтесь с часто задаваемыми вопросами и как спросить< /а>.   -  person marco.m    schedule 28.02.2018


Ответы (1)


Это пример одного из подходов, который вы можете использовать:

(s/def ::tag string?)

(s/def ::inner (s/keys :req-un [::tag]))

(s/def ::outer
  (s/and
    (s/keys :req-un [::inner ::tag])
    #(= (:tag %) ;; this tag must equal inner tag
        (:tag (:inner %)))))

(s/conform ::outer {:tag "y" ;; inner doesn't match outer
                    :inner {:tag "x"}})
;=> :clojure.spec.alpha/invalid

(s/conform ::outer {:tag "x"
                    :inner {:tag "x"}})
;=> {:tag "x", :inner {:tag "x"}}

В зависимости от ваших требований вы можете делать такие утверждения, скорее снаружи внутрь, чем изнутри наружу.

person Taylor Wood    schedule 11.10.2017
comment
Спасибо действительно полезный ответ - person mmer; 01.03.2018