clojure-koans/src/koans/23_meta.clj

52 lines
1.6 KiB
Clojure
Raw Normal View History

(ns koans.23-meta
2015-07-12 20:03:34 +00:00
(:require [koan-engine.core :refer :all]))
(def giants
(with-meta 'Giants
{:league "National League"}))
(meditations
"Some objects can be tagged using the with-meta function"
2019-03-02 17:19:37 +00:00
(= {:league "National League"} (meta giants))
2015-07-12 20:03:34 +00:00
"Or more succinctly with a reader macro"
2019-03-02 17:19:37 +00:00
(= {:division "West"} (meta '^{:division "West"} Giants))
2015-07-12 20:03:34 +00:00
"While others can't"
2019-03-02 17:19:37 +00:00
(= "This doesn't implement the IObj interface" (try
2015-07-12 20:03:34 +00:00
(with-meta
2
{:prime true})
(catch ClassCastException e
"This doesn't implement the IObj interface")))
"Notice when metadata carries over"
2019-03-02 17:19:37 +00:00
(= {:foo :bar} (meta (merge '^{:foo :bar} {:a 1 :b 2}
2015-07-12 20:03:34 +00:00
{:b 3 :c 4})))
"And when it doesn't"
2019-03-02 17:19:37 +00:00
(= nil (meta (merge {:a 1 :b 2}
2015-07-12 20:03:34 +00:00
'^{:foo :bar} {:b 3 :c 4})))
"Metadata can be used as a type hint to avoid reflection during runtime"
2019-03-02 17:19:37 +00:00
(= \C (#(.charAt ^String % 0) "Cast me"))
2015-07-12 20:03:34 +00:00
"You can directly update an object's metadata"
(= 8 (let [giants
(with-meta
'Giants
{:world-series-titles (atom 7)})]
2019-03-02 17:19:37 +00:00
(swap! (:world-series-titles (meta giants)) inc)
2015-07-12 20:03:34 +00:00
@(:world-series-titles (meta giants))))
"You can also create a new object from another object with metadata"
(= {:league "National League" :park "AT&T Park"}
(meta (vary-meta giants
2019-03-02 17:19:37 +00:00
assoc :park "AT&T Park")))
2015-07-12 20:03:34 +00:00
"But it won't affect behavior like equality"
2019-03-02 17:19:37 +00:00
(= giants (vary-meta giants dissoc :league))
2015-07-12 20:03:34 +00:00
"Or the object's printed representation"
2019-03-02 17:19:37 +00:00
(= "Giants" (pr-str (vary-meta giants dissoc :league))))