When building a DSL that creates property delegate...
# getting-started
d
When building a DSL that creates property delegates (backed by a JsonObject, basically), which of these would you expect: 1. Properties are required by default, but could be made optional with
.optional()
2. Properties are optional by default, but could be made required with
.required()
3.
.optional()
vs
.required()
always need to be specified 4. Required properties are not nullable by default: They are expected to exist in the JsonObject, and not be JsonNull. 5. Required properties are nullable by default: They are expected to exist in the JsonObject, but my be JsonNull. 6. Nullability on required properties should always be explicitly declared (eg,
.nonNull()
and
.nullable()
) 7. Setting an optional property to null will remove the key from the JsonObject. 8. Setting an optional property to null will set the key to JsonNull. 9. Nullability on optional properties must always be explicitly declared (eg.
.unsetOnNull()
, and
.storeNulls()
) 10. Some other set of behaviors not listed here.
🤔 1
To clarify, what it will look like:
Copy code
val name by string("name").required().nonNull()
val age by int("age").required().nonNull()
val address by string("address").optional().storeNulls()
val favoriteColor by string("color") // default requiredness/nullability
a
I think it makes more sense to have the properties be required by default, similar to how normal parameters are required (non null) unless specified by adding the question mark. Also, points 7 and 8 seem to contradict each other
d
Thanks. Yes, some of the points are opposite. My question was which of the behaviors would you expect. Does 7 or 8 make more sense?
a
My bad, it is sort of a tricky situation since there’s not both an undefined and null to use like in javascript, but I personally think it would make sense for it to set it to JsonNull and then maybe have some other type of mechanism if you wanted remove the key entirely
c
The main thing here is the difference between being explicitly set to
null
and "presence". First, when I'm reading JSON, in almost all situations I find reasonable to read missing data as
null
. I think that's less surprising than having to treat JSON's
null
as
JsonNull
or whatever other thing that Kotlin
null
. For the cases where the difference is meaningful, you could have a
isPresent
or
has
or
in
method to check the presence of a field.
d
Yes, on the
JsonObject
class itself, there are methods for checking whether or not the key exists. It actually implements
MutableMap<String, JsonElement>
. The delegates will be available only within
JsonObjectWrapper
subclasses, which will also give you access to the underlying JsonObject if necessary.
c
Do you have examples of intended usage with reading and writing?
d
My example above would also work with
var
(I wasn't paying attention and meant to use var actually)
c
I mean, that's an example of declaration of fields. Do you have an example of actually using the declared fields?
d
Copy code
var name by string("name").required().nonNull()
var age by int("age").required().nonNull()
var address by string("address").optional().storeNulls()
var favoriteColor by string("color") // default requiredness/nullability
Copy code
myObj.name = "Bob"
myObj.age = 42
myObj.address = null // Stores JsonNull
myObj.favoriteColor = null // Removes `color` from the object.
The other option was thinking of is creating a
.ref()
method that returns basically a mutable optional that is backed by the object:
Copy code
var address: OptionalPropertyReference<String?> by string("address").optional().storeNulls().ref()
// ...
// address.isSet
// address.clear()
// address.set("123 Mulberry Ln")
// address.set(null)
// etc...