1

I need to call a sort method of a library that takes an implicit Ordering parameter by using implicitly like this:

class OrderedRDDFunctions[K : Ordering : ClassTag,
                          V: ClassTag] (self: RDD[P]) {

  private val ordering = implicitly[Ordering[K]]

  def sort() = {
    // uses ordering value
  }
}

Now, I need to call this function twice in a loop, with different Orderings of same type like below.

var A: RDD[(Int, Int, Int)] = ...
var C: RDD[(Int, Int, Int)] = ...

while(...) {

    implicit val ijOrdering:Ordering[(Int, Int, Int)] = new Ordering[(Int, Int, Int)] {
      override def compare(a: (Int, Int, Int), b: (Int, Int, Int)) = {
        val c = a._1.compare(b._1)
        if(c != 0) c
        else a._2.compare(b._2)
      }
    }
    A.sort() // should use ijOrdering above

    implicit val kjOrdering:Ordering[(Int, Int, Int)] = new Ordering[(Int, Int, Int)] {
      override def compare(a: (Int, Int, Int), b: (Int, Int, Int)) = {
        val c = a._3.compare(b._3)
        if(c != 0) c
        else a._2.compare(b._2)
      }
    }
    C.sort() // should use kjOrdering above

}

There are two different implicit Ordering instances to be used in sort() method. But this gives me a compile error. How can I state different implicit ordering in this setup? Note that I cannot change the library method.

bekce
  • 3,782
  • 29
  • 30

1 Answers1

3

You can use blocks to limit the scope of implicits. A simple example:

object Blocks extends App {
  def meth()(implicit e: Int) = e * 2

  locally {
    implicit val k = 21
    println(meth()) // finds k and prints 42
  }

  locally {
    implicit val j = 11
    println(meth()) // finds j and prints 22
  }
}

This does not work if there are conflicting implicits outside of the block.

Note that locally { ..stmts.. } is generally equivalent to { ..stmts.. }, tho I prefer it for readability's sake. You can read more on what's that here

Oleg Pyzhcov
  • 7,323
  • 1
  • 18
  • 30