Reputation: 262
When creating a type via deftype in clojurescript:
(deftype SomeObject [a b c]
Object
(update [_]
(set! (.-a _) 5)
(set! (.-b _) 6) ))
Is there a possibility to extend the constructor? I would like to do some initialization of my object when it's being created!
Upvotes: 4
Views: 1020
Reputation: 262
Thanks guys, I will go with factory methods then. Probably makes the most sense in ClojureScript anyway! Think I'll try to avoid deftypes/Types in the future, so a factory method can hide that pretty well. Still in the transitioning phase to functional programming ;)
Upvotes: 0
Reputation: 84331
There is no support for that in deftype
, no; the Clojure(Script) equivalent is to define a factory function, perhaps make-some-object
, and use that instead of the actual constructor. See amalloy's answer for an example and rationale.
Of course in JavaScript, constructors are simply functions and you can certainly use ClojureScript to define a function which will work as a JS constructor would:
;; "constructor" with default field values
(defn Point [x y]
(this-as this
(set! (.-x this) (if x x 10)) ; NB. Clojure truth semantics are used
(set! (.-y this) (if y y 20))))
(.-x (Point. 2))
;= 2
(.-y (Point. 2))
;= 20
That goes against the overall spirit of the language a bit, and so is not advisable except in special circumstances. (Interop with a JS API expecting a constructor as an argument perhaps?)
Upvotes: 4
Reputation: 91857
The constructor for a deftype is intentionally minimalistic: it just copies N objects to hold your data fields. There's no need to make it more powerful, because you already have a tool to do the job: plain old functions are all you need.
(defn foo [opts]
(if-not (acceptable? opts)
(throw (Exception. "No way, man"))
(Foo. (:x opts) (:y opts)))
is a simple example of wrapping a deftype constructor. Even if deftype allowed you to imbue a "real" constructor with this sort of logic, it's nice to create an abstraction barrier between the client API and the underlying representation, so that client code can be mainly unaffected if the representation changes.
Upvotes: 3