I'm playing around with kotlin `contracts` and hav...
# announcements
b
I'm playing around with kotlin
contracts
and have run into a problem I need some expert help with. I'm trying to validate user input from a method that takes a couple of nullable parameters and would like to use
contracts
and the below
checkParamIsNotNullOrBlank
-function to avoid null checks at the end of my expression. Here's a simplified example of what I'm trying to achieve:
Copy code
@ExperimentalContracts
    override fun validateInput(
        firstParam: String?,
        secondParam: String?,
        thirdParam: String?,
        listener: ValidationListener?) {
        var error: Boolean
        error = isParamNullOrBlank(firstParam) { view?.firstParamEmptyError() }
        if (secondParam.isNullOrBlank()) {
            view?.secondParamEmptyError()
            error = true
        }
        if (thirdParam.isNullOrBlank()) {
            view?.thirdParamEmptyError()
            error = true
        }
        if (error == false) {
            val validObject = Object.Builder()
                .withFirstParam(firstParam)
                .withSecondAndThirdParam("$secondParam^$thirdParam")
                .create

            listener?.onValidated(validObject)
        }
    }
Here's my "contracts"-method:
Copy code
@ExperimentalContracts
fun isParamNullOrBlank(param: String?, onInvalid: (() -> Unit)? = null) : Boolean {
    contract {
        returns(false) implies (param != null)
    }
    val result = param.isNullOrBlank()
    onError?.invoke()
    return result
}
This doesn't compile because the compiler can't infer that
firstParam
is not null. Also every
if
expression should be evaluated as the view can display multiple errors.
k
Well, the compiler simply cannot infer that
firstParam
is not null. It could do it if you would use the result of
checkParamIsNotNullOrBlank
in an
if
expression directly, but it cannot do it here because
error
being mutable and modified breaks the contract. In fact creating a variable out of the result of contract methods breaks it already.
b
@kralli Ahh of course. Thanks.