Solution 1 :
As suggested by Egor, an expression body is not always the best solution. Rewrote it to this.
suspend operator fun invoke(reference: Reference): Date {
val tag = reference.tagId?.let { tagRepository.getTag(it)}
val uploadDateOrNow = tag?.uploadDate ?: Date()
uploadDateOrNow.time += defaultExpiryPeriod()
return uploadDateOrNow.roundToMidnight()
}
private suspend fun defaultExpiryPeriod() = accountRepository
.getAccount().first()
.defaultExpiryPeriod
Working on a project of my own and boy, do I miss being criticized in PRs ones in a while.
Problem :
I came across a strange bug and I can’t figure out why it occurs. If I invoke my original function, roundToMidnight()
is not called and the date is not rounded.
My original function, what doesn’t work:
suspend operator fun invoke(reference: Reference) = reference.tagId
?.let { tagRepository.getTag(it) }
?.uploadDate ?: Date()
.apply { time += accountRepository.getAccount().first().defaultExpiryPeriod }
.roundToMidnight()
}
What does work:
suspend operator fun invoke(reference: Reference): Date {
val date = reference.tagId
?.let { tagRepository.getTag(it) }
?.uploadDate ?: Date()
.apply { time += accountRepository.getAccount().first().defaultExpiryPeriod }
return date.roundToMidnight()
}
roundToMidnight()
returns a new instance of Date
fun Date.roundToMidnight(): Date {
val calendar = Calendar.getInstance()
calendar.time = this
calendar[Calendar.HOUR_OF_DAY] = 23
calendar[Calendar.MINUTE] = 59
calendar[Calendar.SECOND] = 59
calendar[Calendar.MILLISECOND] = 0
return Date(calendar.timeInMillis)
}
What causes the differences in both functions? I’d say they would be exactly the same and I see myself refactoring the bugless function into the original in a month time, because I forgot this happens.
Comments
Comment posted by IR42
apply
Comment posted by Michiel
Thank you! Could it be inlined so
Comment posted by IR42
use brackets
Comment posted by Egor
I’d highly recommend rewriting this snippet of code without using