Is there a better way to use the immutable builder...
# announcements
s
Is there a better way to use the immutable builder pattern than this ?
Copy code
fun LocalDate.set(year: Int?, month: Int?, day: Int?) : LocalDate {
    var tmp = this
    if (year != null){
        tmp = tmp.withYear(year)
    }
    if (month != null){
        tmp = tmp.withMonth(month)
    }
    if (day != null){
        tmp = tmp.withDayOfMonth(day)
    }
    return tmp
}
b
probably you will find this better:
Copy code
fun LocalDate.set(
        newYear: Int = year,
        newMonth: Int = monthValue,
        newDay: Int = dayOfMonth
    ): LocalDate {
        return withYear(newYear).withMonth(newMonth).withDayOfMonth(newDay)
    }
then call will be:
date.set(newYear = 2019, newMonth = 3)
or
date.set(newDay = 10)
// or at least you could add default null values to your version, so you don't need to call
date.set(2020, null, null)
if you want to update only year - it will be
date.set(2020)
or
date.set(month = 2)
if you want update only month
Copy code
fun LocalDate.set(
        year: Int = this.year,
        month: Int = monthValue,
        day: Int = dayOfMonth
    ): LocalDate {
        return withYear(year).withMonth(month).withDayOfMonth(day)
    }
my updated version without ugly
new
prefix for parameter names
☝️ 1
s
The nullable values come from another place so default values doesnt really fit the bill well. It is the function body I would like to improve. Not its signature
k
But if the value is null, what does the function do? It uses the value’s current values as the default. So why not change the function signature to have default values representing year-now, month-now, etc. and then you can simplify the function body by getting rid of the null checks and doing what Denis suggested above.
You have to handle the null cases somewhere by either replacing them or ignoring (which is effectively the same as replacing with the current value)
Actually you could do something like
Copy code
tmp
  .withYear(year ?: this.year)
  .withMonth(month ?: monthValue)
  .withDay(day ?: dayOfMonth)
Which lets you leave your function signature alone but makes the null handling terser
s
Nice. I was sort of stuck with the: if null dont call method, but passing in the current value is a nice work around.