Visiting ent nodes is kind of like mapping: when you call
mapon a seq, you apply a mapping function to each element, creating a new seq from the mapping function's return values. When you visit ents, you apply a visiting function to each ent. The visiting function's return value is stored as an attribute on the ent (remember that ents are implemented as graph nodes, and nodes can have attributes).
:spec-genattribute; that's because the
sg/ent-db-spec-genyou called actually applies a visiting function to the ent db it generates. Let's create our own visiting function so you can see how this works:
(ex-01)creates an ent db, applies a visiting function, and then looks up the
:attrskey in the graph associated with the ent db's
:attrskey is where loom stores each node's attributes. We can see that each ent (
:tl0) has an attribute with the key
:announceand the value of
"announcing... :ent-name!". Let's walk through this. You call the function
ex-01, whose body is:
sm/add-entsbuilds the ent db and passes it to
sm/visit-entstakes three arguments: the ent db, a visit key (
:announce), and a visiting function. Then, internally,
sm/visits-entsiterates overs each ent in the ent db, passing the ent's name to the visiting function along with the db and visit key, using the return value to assign an attribute to the ent.
sm/visit-entsiterates over them in that order. For
:u0, it passes the following arguments to the visiting function
:ent-namewhose value is
:ent-namepassed in the second argument to return the string
"announcing... :u0!", and that gets associated with the
:announcekey under the ent's attributes.
announcefunction returns its little string. But how would we use visiting functions to actually insert records into a database? The answer is that the map passed as the second argument to visiting functions contains a lot more information than just the
:ent-nameof the current ent. It also includes the
:post) and, when you're using the clojure.spec visiting function, the
:spec-genvalue. The next section will show you how to combine those values to insert data in a database.
swapon atom, inserting a vector of
[:ent-type :ent-name]for every ent?