Last active
August 29, 2015 14:10
-
-
Save acthp/8f42bf23aa0839811931 to your computer and use it in GitHub Desktop.
clojure bean macro
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(let [t (fn [type prop] ; type hint a property | |
(with-meta prop {:tag type})) | |
cc (fn [prop] ; camel-case a property | |
(str (.toUpperCase (subs (str prop) 0 1)) (subs (str prop) 1))) | |
m (fn [prop method] ; construct method name for property | |
(symbol (str method (cc prop)))) | |
bean-interface (fn [bean-name & props] ; define interface for bean | |
(let [set (fn [type prop] | |
`(~(m prop 'set) [~(t type 's)])) | |
get (fn [type prop] | |
`(~(t type (m prop 'get)) [])) | |
methods (for [[t p] (partition 2 props) method [set get]] | |
(method t p))] | |
`(definterface ~(symbol (str "I" bean-name)) ~@methods))) | |
bean-type (fn [bean-name & props] ; define type for bean | |
(let [prop-list (mapv (fn [[type prop]] | |
(with-meta prop {:volatile-mutable true :tag type})) | |
(partition 2 props)) | |
set (fn [type prop] | |
`(~(m prop 'set) [~'this ~(t type 's)] (set! ~prop ~'s))) | |
get (fn [type prop] | |
`(~(t type (m prop 'get)) [~'this] ~prop)) | |
methods (for [[t p] (partition 2 props) method [set get]] | |
(method t p))] | |
`(deftype ~bean-name ~prop-list java.io.Serializable ~(symbol (str "I" bean-name)) ~@methods)))] | |
(defmacro defbean [bean-name & props] | |
(list 'do | |
(apply bean-interface bean-name props) | |
(apply bean-type bean-name props)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment