Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reference outer object from inner class in Scala

Consider this code (which is kind of type safe units):

abstract class UnitsZone {
   type ConcreteUnit <: AbstractUnit

   abstract class AbstractUnit(val qty: Int) {
     SOME_ABSTRACT_MEMBERS
     def +(that: ConcreteUnit): ConcreteUnit = POINT_OF_INTEREST.apply(this.qty + that.qty)
     def apply(param: Int) = SOME_IMPLEMENTATION
   }

   def apply(qty: Int): ConcreteUnit
}

object Imperial extends UnitsZone {
  type ConcreteUnit = Pound

  class Pound(override val qty: Int) extends AbstractUnit(qty) {
    CONCRETE_MEMBERS_HERE
  }

  def apply(qty: Int) = new Pound(qty)
}

To make the whole thing works I need to invoke apply method of an outer object with respect to inheritance (marked as POINT_OF_INTEREST in the above code). With this in mind I dare to ask several questions:

  1. Is there any way to do it?
  2. If there are many, what are pros and cons for each one?
  3. If you think the whole thing is wrong, what is your right way to implement such functionality?
like image 324
Artem Pyanykh Avatar asked Dec 11 '22 04:12

Artem Pyanykh


1 Answers

Use a self reference:

abstract class UnitsZone {
  outer =>
  type ConcreteUnit <: AbstractUnit
  ...
  abstract class AbstractUnit(val qty: Int) {
    def +(that: ConcreteUnit): ConcreteUnit = outer.apply(this.qty + that.qty)
    ...
  }
}

See chapter 17. Self references of the SO Scala tutorial for more information about what else this construct allows you to do.

like image 95
kiritsuku Avatar answered Jan 06 '23 14:01

kiritsuku