Back
datafy (clj)
(source)function
(datafy x)
Attempts to return x as data.
datafy will return the value of clojure.core.protocols/datafy. If
the value has been transformed and the result supports
metadata, :clojure.datafy/obj will be set on the metadata to the
original value of x, and :clojure.datafy/class to the name of the
class of x, as a symbol.
Examples
clojure/clojurescript
(ns clojure.datafy-test
(:require [cljs.test :as test
:refer-macros [deftest is testing]]
[clojure.datafy :as d]))
(deftest datafy-test
(testing "Datafy works when datafied value is arbitrary JS objects"
(let [datafied #js {}
x (with-meta [1 2 3] {`clojure.core.protocols/datafy (fn [_] datafied)})]
(is (= datafied (d/datafy x)))))
(testing "Datafy adds ::obj metadata when return value != original value and supports metadata"
(let [datafied [2 3 4]
original [1 2 3]
x (with-meta original {`clojure.core.protocols/datafy (fn [_] datafied)})]
(is (= datafied (d/datafy x)))
(is (= {:clojure.datafy/obj original} (meta (d/datafy x)))))))
(deftest datafy-js-errors-test
(let [x (js/Error. "foo")]
(is (= (Throwable->map x) (d/datafy x))))
;; Ensure we can datafy objects that extend js/Error
(let [x (js/RangeError. "x must be between 1 and 5")]
(is (= (Throwable->map x) (d/datafy x)))))
(deftest datafy-ex-info-test
(let [x (ex-info "foo" {:a 1} (ex-info "bar" {:b 2}))]
(is (= (Throwable->map x) (d/datafy x)))))
clojure/clojurescript
(ns test-runner
(:require [cljs.test :refer-macros [run-tests]]
[cljs.apply-test]
[cljs.primitives-test]
[cljs.destructuring-test]
[cljs.new-new-test]
[cljs.printing-test]
[cljs.seqs-test]
[cljs.collections-test]
[cljs.hashing-test]
[cljs.core-test :as core-test]
[cljs.reader-test]
[cljs.binding-test]
[cljs.parse-test]
[cljs.ns-test]
[clojure.set-test]
[clojure.string-test]
[clojure.data-test]
[clojure.datafy-test]
[clojure.edn-test]
[clojure.walk-test]
[clojure.math-test]
[cljs.macro-test]
[cljs.letfn-test]
[foo.ns-shadow-test]
[cljs.top-level]
[cljs.reducers-test]
[cljs.keyword-test]
[cljs.import-test]
[cljs.ns-test.foo]
[cljs.syntax-quote-test]
[cljs.pprint]
[cljs.pprint-test]
[cljs.spec-test]
[cljs.specials-test]
[cljs.spec.test-test]
[cljs.clojure-alias-test]
[cljs.hash-map-test]
[cljs.map-entry-test]
[cljs.metadata-test]
[cljs.npm-deps-test]
[cljs.other-functions-test]
[cljs.predicates-test]
[cljs.tagged-literals-test]
[cljs.test-test]
[static.core-test]
[cljs.recur-test]
[cljs.array-access-test]
[cljs.inference-test]
[cljs.walk-test]
[cljs.repl-test]
[cljs.extend-to-native-test]))
(run-tests
'cljs.apply-test
'cljs.primitives-test
'cljs.destructuring-test
'cljs.new-new-test
'cljs.printing-test
'cljs.seqs-test
'cljs.collections-test
'cljs.hashing-test
'cljs.core-test
'cljs.reader-test
'cljs.parse-test
'clojure.set-test
'clojure.string-test
'clojure.data-test
'clojure.datafy-test
'clojure.edn-test
'clojure.walk-test
'clojure.math-test
'cljs.letfn-test
'cljs.reducers-test
'cljs.binding-test
'cljs.macro-test
'cljs.top-level
'cljs.keyword-test
'cljs.ns-test
'cljs.ns-test.foo
'foo.ns-shadow-test
'cljs.import-test
'cljs.pprint
'cljs.spec-test
'cljs.specials-test
'cljs.spec.test-test
'cljs.clojure-alias-test
'cljs.hash-map-test
'cljs.map-entry-test
'cljs.metadata-test
'cljs.npm-deps-test
'cljs.other-functions-test
'cljs.pprint-test
'cljs.predicates-test
'cljs.syntax-quote-test
'cljs.tagged-literals-test
'cljs.test-test
'static.core-test
'cljs.recur-test
'cljs.array-access-test
'cljs.inference-test
'cljs.walk-test
'cljs.repl-test
'cljs.extend-to-native-test)
babashka/babashka
(ns babashka.impl.protocols
(:require [babashka.impl.protocols :as protocols]
[clojure.core.protocols :as p]
[clojure.datafy :as d]
;; ensure datafy is loaded, we're going to override its
;; clojure.lang.Namespace implementation for datafy
[clojure.reflect]
[sci.core :as sci :refer [copy-var]]
[sci.impl.types :as types]
[sci.impl.vars]))
;;;; datafy
(defmulti datafy types/type-impl)
(defmethod datafy :sci.impl.protocols/reified [x]
(let [methods (types/getMethods x)]
((get methods 'datafy) x)))
(defmethod datafy :default [x]
;; note: Clojure itself will handle checking metadata for impls
(d/datafy x))
(def protocols-namespace
{;; Datafiable
'Datafiable (sci/new-var 'clojure.core.protocols/Datafiable {:methods #{'datafy}
:protocol p/Datafiable
:ns protocols-ns}
{:ns protocols-ns})
'datafy (copy-var datafy protocols-ns)
nextjournal/clerk
;; # 🖨 Better Printing ADR
^{:nextjournal.clerk/visibility {:code :hide}}
(ns ^:nextjournal.clerk/no-cache viewers.printing
(:require [clojure.datafy :as datafy]
[clojure.java.io :as io]
[clojure.set :as set]
[clojure.string :as str]
[nextjournal.clerk :as clerk :refer [with-viewer]]
[nextjournal.clerk.viewer :as v]))
;; Initially I thought we'd use `clojure.core/datafy` in case there's a non-trivial implementation for a given object.
;; But I rejected this because the default implementations for `class` and `namespace` would be confusing.
(type (atom {}))
(datafy/datafy (type (atom {})))
(datafy/datafy #'inc)
(datafy/datafy (find-ns 'nextjournal.clerk))
hyperfiddle/electric
(ns dustin.y2022.file-watcher
(:require [clojure.java.io :as io]
[clojure.java.data :as j]
[clojure.datafy :refer [datafy]]
[leo.file-watcher :refer [watch-dir
read-edn-forms
watch-file
path]]
[hyperfiddle.rcf :as rcf :refer [tests % tap]]
[missionary.core :as m]))
(def x @!x)
(bean x)
(datafy x)
(j/from-java x)
(str x)