Last active
September 4, 2016 13:51
-
-
Save guruma/bd97dd262f63c14ec45475f898a4d198 to your computer and use it in GitHub Desktop.
def-type : 멤버 변수 접근자 함수를 간단하게...
This file contains hidden or 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
(defmacro ? [o prop] | |
(let [get-prop# (symbol (str "get-" prop))] | |
`(~get-prop# ~o))) | |
(defmacro ! [o prop val] | |
(let [set-prop# (symbol (str "set-" prop))] | |
`(~set-prop# ~o ~val))) | |
(defmacro def-access-method [field] | |
(let [get-method# (symbol (str "get-" field)) | |
set-method# (symbol (str "set-" field))] | |
`((~get-method# [~'this]) | |
(~set-method# [~'this ~'val])))) | |
(defmacro def-access-methods [fields] | |
(let [methods# (for [field# fields] | |
(macroexpand `(def-access-method ~field#))) | |
methods'# (apply concat methods#) | |
] | |
`(~@methods'#))) | |
(defmacro def-access-method-impl [field] | |
(let [get-method# (symbol (str "get-" field)) | |
set-method# (symbol (str "set-" field))] | |
`((~get-method# [~'this] (. ~'this ~field)) | |
(~set-method# [~'this ~'val] (set! ~field ~'val))))) | |
(defmacro def-access-method-impls [fields] | |
(let [method-impl# (for [field# fields] | |
(macroexpand `(def-access-method-impl ~field#))) | |
method-impls'# (apply concat method-impl#) | |
] | |
`(~@method-impls'#))) | |
(defmacro def-type [name fields] | |
(let [protocol# (symbol (str name "Accessable")) | |
methods# (macroexpand `(def-access-methods ~fields)) | |
method-impls# (macroexpand `(def-access-method-impls ~fields)) | |
mutable-fields# (mapv #(with-meta % {:volatile-mutable true}) fields) | |
] | |
`(do (defprotocol ~protocol# ~@methods#) | |
(deftype ~name ~mutable-fields# ~protocol# ~@method-impls#)))) | |
(def-type Person [name age]) | |
(def person (Person. "John" 27)) ;=> #'ns/person | |
(? person age) ;=> 27 | |
(! person age 29) ;=> 29 | |
(? person age) ;=> 29 | |
(? person name) ;=> "John" | |
(! person name "Tom") ;=> "Tom" | |
(? person name) ;=> "Tom" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment