jbrown
jbrown

Reputation: 7986

Scala traits exposing protected members?

Given a class like:

class MyClass {
    protected object MyObj { ... }
}

is it possible to write a trait that will permit exposing MyObj. E.g. with inheritance I could do the following:

class TestMyClass extends MyClass {
    val getMyObj = MyObj
}

but I want to do this via a trait, something like the following which doesn't typecheck:

trait ExposeMyObj {
    val getMyObj = MyObj        // super.MyObj/this.MyObj don't work 
}

and use it like:

class TestMyClass extends ExposeMyObj

Is it possible to reproduce the functionality in TestMyClass into a trait to expose the protected object, and if so how?

Upvotes: 0

Views: 1185

Answers (1)

Shadowlands
Shadowlands

Reputation: 15074

If you know that your trait will always be mixed in to an instance of MyClass (or a subclass), you can enforce the expectation with a self-type, and then access the object:

trait ExposeMyObj {
    self: MyClass =>

    val getMyObj = MyObj
}

Edit: an example of using this trait:

class TestMyClass extends MyClass with ExposeMyObj

val test = new TestMyClass
test.getMyObj // accesses MyObj defined in MyClass.

Edit 2: attempting to address @jbrown's comment (re: testing queries within repos) - I would look at doing something like the following - first, in each repo's file, add a trait for each repo holding the queries for that repo:

trait UserQueries { // you could look at making this protected, if you like

  protected def query1(param: String) = List(param) // very silly implementation, but hopefully enough to make the point
  ... // other queries
}

class UserRepo extends UserQueries // Has (internal) access to those queries

Then in the test class file for a given repo:

class UserQueriesTester extends UserQueries with ScalaTest { // or whatever test framework you are using

  // (public) tests to run - eg:
  def testQuery1 = query1("test") should be (List("test"))

}

Upvotes: 1

Related Questions