You cannot modify or customize the constructor functions that defrecord
and deftype
create.
It’s common to want additional functionality around constructing an object, such as validation and default values. To get this, just define your own constructor function that wraps the default constructor.
(defrecord Customer [id name phone email]) (defn customer "Creates a new customer record." [{:keys [name phone email]}] {:pre [(string? name) (valid-phone? phone) (valid-email? email)]} (->Customer (next-id) name phone email))
You don’t necessarily have to use :pre
conditions for validation; that’s just how I wrote this example.
It’s up to you to maintain a convention to always use your custom constructor function instead of the automatically-generated one.1
I frequently define a custom constructor function for every new record type, even if I don’t need it right away. That gives me a place to add validation later, without searching for and replacing every instance of the default constructor.
Even custom constructor functions should follow the rules for safe constructors. In general, that means no side effects and no “publishing” the object to another place before the constructor is finished. Keep the “creation” of an object (the constructor) separate from “starting” or “using” it, whatever that means for your code.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.3