Reputation: 5702
I have an app that extends App and a trait that implements an option parser. All the trait needs is that some class or trait in the runtime mix provides:
val args: Array[String]
If I declare:
trait OptionParser extends App {...}
All is fine but that rules out any other use of the option parser than with an App object. Not sure if there are inefficiencies in having the app extend App as well as mixing in OptionParser as with:
object MyApp extends App with OptionParser {...}
I realize this could be shortened to:
object MyApp extends OptionParser {...}
But ideally I'd like to make OptionParser completely independent except for relying on args
to be provided and this is only because that's where App puts them.
Is there some way to declare a dependency without providing the class or trait to take it from? An error could be detected at link time so as not to break type safety.
Upvotes: 0
Views: 272
Reputation: 7466
Not sure I understand exactly what you are trying to do. How about that:
trait OptionParser {
protected def args: Array[String]
}
This way, you can mixin OptionParser
with anything that provides a args
, not necessarily App
.
Edit: since App
defines args
visibility as protected
you need to do that in OptionParser
as well. This is unfortunate. Here is another idea:
trait OptionParser {def options: Array[String] ... }
object MyApp extends App with OptionParser {def options = args ...}
Upvotes: 6
Reputation: 55569
You can do this with a self type declaration on OptionParser
. This will require types that mix in OptionParser
to be an App
, without mixing in App
itself.
trait OptionParser { this: App =>
def test(): Unit = {
println("test")
println(args)
}
}
object Test extends App with OptionParser {
test()
println("done")
}
Upvotes: 2