Inheriting a self-tuning trait with a different trait in Scala

I am trying to create a small module system for my application so that I can do this:

new MyApplication extends Module1 with Module2 ... with ModuleN

In order for my modules to register in the application, I also have:

trait ModuleRegistry {
  def register(start: () => Unit) = // Stores start functions in a list
}

trait Module {
  self: ModuleRegistry =>
  self.register(start)
  def start(): Unit
}

class Application extends ModuleRegistry {
}

trait Module1 extends Module {
  ...
}

The idea is that modules can register a function with a registry that will be called when the application starts. Unfortunately, the Scala compiler forces me to do this:

trait Module1 extends Module {
  self: ModuleRegistry =>
}

means that all implementations of the module should explicitly configure themselves with the registry when, ideally, they do not know about it.

So my questions are:

  • ? , "" , . "" , .
  • , Scala, ?
+4
1

, , (), . , : , , , .

" ".

trait Module {
  def start: Unit
}

trait Modular {
  protected def moduleList: Seq[Module]
  protected def register() = moduleList.map(m => m.start _)
}

class Application(modules: Module*) extends Modular {
  protected def moduleList: Seq[Module] = modules  // Fix varargs type
  protected val registered = register()
}

object Module1 extends Module {
  def start = println("One")
}

object Module2 extends Module {
  def start = println("Two")
}

val app = new Application(Module1, Module2) {
 registered.foreach(_())
}
// Prints "One", then "Two"

, . , ( - 1()) , , Module1 (, trait ModuleBuilder { def module: Module }).

+6

Source: https://habr.com/ru/post/1598624/


All Articles