Create a gist now

Instantly share code, notes, and snippets.

// 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
[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
@lazyval
lazyval commented Feb 1, 2013

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.

@stephanos
Owner

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

@pfalabella

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment