Ruby vs Kotlin: Custom Comparable classes

Often it's nice to be able to sort custom objects and compare which one is bigger or smaller. Today we are going to implement such MyDate class in Ruby and Kotlin. I found it interesting that interfaces in Kotlin, similarly to modules in Ruby, can contain an implementation. Let's see a very simple example.

First in Ruby:

class MyDate < Struct.new(:year, :month, :day_of_month)
  include Comparable

  def <=>(other)
    diff_year = year - other.year
    return diff_year if diff_year.nonzero?

    diff_month = month - other.month
    return diff_month if diff_month.nonzero?
    
    day_of_month - other.day_of_month
  end
end

def check_in_range(date, first, last)
  Range.new(first, last).cover?(date)
end


and now in Kotlin.

data class MyDate(
  val year: Int, 
  val month: Int, 
  val dayOfMonth: Int
) : Comparable {
    override operator fun compareTo(other: MyDate): Int {
        val diffYear = year - other.year
        if (diffYear != 0) { return diffYear }

        val diffMonth = month - other.month
        if (diffMonth != 0) { return diffMonth }

        return dayOfMonth - other.dayOfMonth
    }
}

class DateRange(
  override val start: MyDate,
  override val endInclusive: MyDate
) : ClosedRange

fun checkInRange(date: MyDate, first: MyDate, last: MyDate): Boolean {
    return date in DateRange(first, last)
}

You might wonder where is the implemented interface that I mentioned. Check it out:

package kotlin.ranges

public interface ClosedRange<T: Comparable<T>> {
    public val start: T
    public val endInclusive: T

    public operator fun contains(value: T): Boolean = 
      value >= start && value <= endInclusive

    public fun isEmpty(): Boolean = start > endInclusive
}

As you can see, there are many similarities. But I prefer explicit dependencies between interfaces like that fact that ClosedRange requires data which is Comparable.





Popularne posty z tego bloga

re-enable tray icons in ubuntu 13.10?