pferrel
pferrel

Reputation: 5702

Scala: Using the App trait

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

Answers (2)

vptheron
vptheron

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

Michael Zajac
Michael Zajac

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

Related Questions