public
Last active

  • Download Gist
cake-pattern.scala
Scala
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
// Library
// =================================================
trait ConfigComp {
 
trait Config {
def get(k: String): String
}
 
def config: Config
}
 
trait QueueComp {
self: ConfigComp =>
 
class Queue {
val key = config.get("some-key")
}
 
lazy val queue = new Queue
}
 
// Application
// =================================================
 
object MyConfig extends ConfigComp {
val config = new Config {
println("INITIALIZING CONFIG")
 
def get(k: String) = "value"
}
}
 
trait MyConfig extends ConfigComp {
 
lazy val config = MyConfig.config
}
 
object Frontend extends QueueComp with MyConfig
object Backend extends QueueComp with MyConfig
 
Frontend.queue.key
Backend.queue.key
output
1 2 3 4 5
[error] overriding method config in trait ConfigComp of type => MyConfig.this.Config;
[error] lazy value config has incompatible type
[error] lazy val config = MyConfig.config
[error] ^
[error] one error found

I don't know exactly why nested trait doesn't work, but this one should.

trait Config {
    def get(k: String): String
}

trait ConfigComp {
  def config: Config
}

trait QueueComp {
  self: ConfigComp =>

  class Queue {
    val key = config.get("some-key")
  }

  lazy val queue = new Queue
}

object SharedConfig {
  val config= new Config {
    println("INITIALIZING CONFIG")

    def get(k: String) = "value"
  }
}

trait MyConfig extends ConfigComp {

  lazy val config = SharedConfig.config
}

Not sure if this helps a lot.

that seems to work! great, thanks for your help!

if you nest Config in ConfigComp, it should work by doing this:

trait ConfigComp {

  trait Config {
    def get(k: String): String
  }

  def config: ConfigComp#Config
}

search for path-dependent types for more info.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.