Unknown section heading | Preserve; do not error
大多数人认为严格的格式规范应该拒绝未知或不合规的部分,以确保一致性。但作者选择保留未知标题而不报错,这表明设计系统应该允许扩展和进化,而不是被严格规范所限制,这是一种反直觉的开放性设计原则。
Unknown section heading | Preserve; do not error
大多数人认为严格的格式规范应该拒绝未知或不合规的部分,以确保一致性。但作者选择保留未知标题而不报错,这表明设计系统应该允许扩展和进化,而不是被严格规范所限制,这是一种反直觉的开放性设计原则。
Technical specs have immense benefits to everyone involved in a project: the engineers who write them, the teams that use them, even the projects that are designed off of them
Benefits: 1. as developer, easy to solve problem 2. as team, easy to do team work 3. as Project manager, easy postmortems
Another problem was the ambiguity of RFC 3066 regarding the generative syntax. The idea of "language-dash-region" language tags was easy enough to grasp; most users didn't read RFC 3066 directly or consider the unstated-but-realized implication that other subtags might sometimes occur in the second position.
unstated-but-realized
I'm looking at https://html.spec.whatwg.org/#attributes-3 right now, and it seems that there are a few others that ought to be boolean but are not currently in this list: allowpaymentrequest, formnovalidate, hidden (is on the original list in the master branch), itemscope, nomodule, and playsinline.
data- attribute names containing underscores
data- attribute names containing underscores
However, we found a few trade-offs when using clojure.spec: clojure.spec requires registering a spec for each key in every path that you care about in a data structure, which can be verbose, especially for deeply-nested data structures. We felt this pain the most when specifying the incoming webhook payloads from the providers. We didn't specify the full payloads, we only specified the values that we actually needed, some of which were nested 7-8 levels deep. To work around this, we used data-spec (part of the spec-tools project) to define the payload specs as a mirror of the shape of the actual data. clojure.spec's error output is concise, and it's not always immediately apparent where the validation failure is within the data, especially when validating a large data structure. To help with this, we used expound to generate friendlier error messages at the REPL and in tests.
spec gotchas
This system is the first significant project on which we have used clojure.spec, and it proved useful in a few ways: Specifying the inputs to each layer in one place made it easier to visualize the shape of the data as it flowed through the subsystem, and proved valuable when describing the behavior to other engineers.Instrumenting the inputs and outputs of our layer boundary functions (via Orchestra), during testing, enabled us to quickly catch cases where we deviated from the spec, allowing us to see the issue at that boundary instead of as a random error within the implementation. Validating the layer inputs against our specs in production allows us to quickly diagnose and isolate faults to the layer where it was triggered, and helps us catch when our assumptions about the shape of the webhook event are incorrect. Having specs allowed for more straightforward tests, since we didn't need to assert on the shape of the data.
benefits of spec
(s/def :ring.http/field-name (-> (s/and string? not-empty field-name-chars?) (s/with-gen #(gen/not-empty (gen-string field-name-chars)))))
clean way of using with gen!
(defn- gen-string [chars] (gen/fmap str/join (gen/vector (gen/elements chars)))) (defn- gen-query-string [] (->> (gen/tuple (gen/not-empty (gen/string-alphanumeric)) (gen-string uri-chars)) (gen/fmap (fn [[k v]] (str k "=" v))) (gen/vector) (gen/fmap #(str/join "&" %)))) (defn- gen-method [] (gen/fmap keyword (gen/not-empty (gen-string lower-case-chars)))) (defn- gen-input-stream [] (gen/fmap #(java.io.ByteArrayInputStream. %) (gen/bytes))) (defn- gen-exception [] (gen/fmap (fn [s] (Exception. s)) (gen/string-alphanumeric)))
nice lesson on generators
(defn- char-range [a b] (map char (range (int a) (inc (int b))))) (def ^:private lower-case-chars (set (char-range \a \z)))
nice way of defining character range
function coll-of allows a :count key to specify the required number of elements:
good to know that there is the keyword directive :count
On the flip side, it can go further than mere types, including emulating dependent types and programming-by-contract.
spec though it's used at runtime (not compile time)
The things they learn to do in WordPress are generalizable to other systems and other online spaces
generated
Mass Spectrometry of Structurally Modified DNA
extensive review
If the exclude fragment flag is unset and url’s fragment is non-null, append "#", followed by url’s fragment, to output.
If the given value is the empty string, set context object’s url’s fragment to null and terminate these steps