Selecting Object literals
(obj) selects Object literals and, optionally, their properties -- similar to what (arr) does for Array literals. It has the following signature:
(obj [props?])In its bare form, (obj) will match any Object, like {} or {a}:
(obj)To select an object based on its properties, the (prop) selector can be used, which is also analogous to (el) for Array elements. It has the following signature:
(prop [key?] [val?])The following query selects an object that has a property named by the identifier x:
(obj (prop x))Property names are not restricted to identifiers: they can be strings -- { "a": 1 }, or numbers -- { 3: 1 }, or computed -- { [a]: 1 }. To be specific about the type of a key, we can use one of the corresponding selectors we've encountered before:
(obj (prop (str a))) ; { "a": 1 }
(obj (prop (comp (num)))) ; { [3]: 1 }Property values can be selected in a similar fashion by providing a selector as the second argument to (prop):
(obj (prop x (str))) ; { x: "foo" }When the property name is irrelevant, disregard it using the placeholder atom:
(obj (prop _ (str))) ; { x: "foo" }
; { [x]: "foo" }Selecting objects based on multiple properties
As we've seen with Arrays in the introduction to the logical operators, we can use (:and) to combine multiple (prop) selectors and cover more than one property of an object. Say we want to select an object that has the properties named "headers" and "url":
(obj (:and (prop headers)
(prop url)))Alternating with (:or) and excluding with (:not) behave similarly. Alternates are especially useful for property selection since property names (keys) may be more than identifiers; a problem we did not have with Arrays. For example, to match the "headers" and "url" properties regardless of whether they are defined as an identifier or a string:
(obj (:and (prop (:or (id headers) (str "headers")))
(prop (:or (id url) (str "url")))))Such patterns are often necessary and could get unwieldy rather quickly; consider that a name may also be a computed property of a string literal:
(obj (:and (prop (:or (id headers) (str "headers") (comp (str "headers"))))
(prop (:or (id url) (str "url") (comp (str "url"))))))SYNG provides dedicated constructs for dealing with these patterns. We discuss this in more detail later in the chapter on supertype selection.