Reputation: 15103
The following code:
trait TestMainArgs extends App {
println(s"args are: $args") // I need to have a generic main in trait which refers to args...
}
object MyRealMainObj extends TestMainArgs {
// I do not want to call the generic main from objects this would mean I would need to call them from every object which extendfs TestMainArgs
}
prints:
args are: null
While the following:
trait TestMainArgs extends App {
}
object MyRealMainObj extends TestMainArgs {
println(s"args are: $args")
}
prints:
args are: [Ljava.lang.String;@f82f98
So how can I access args from the trait?
I want to put the logic of the "main"
only in the super trait
and I don't want code duplication like calling from every object which extends app the super main, is there any way to achieve that?
Upvotes: 2
Views: 142
Reputation: 67075
Another option that is also deprecated is to override main
:
trait TestMainArgs extends App {
override def main(args: Array[String]) {
println(s"args are: ${args(0)} from test")
super.main(args)
}
}
The problem is that the way traits are compiled, the constructor is triggered before the main object, which is where args
is set. There appears to be no non-deprecated means to do this...
Upvotes: 3
Reputation: 1936
The answer lies in looking at both DelayedInit and App in the Scala source. The real gem lies in the doc comment at the start of DelayedInit:
Example:
* {{{
* trait Helper extends DelayedInit {
* def delayedInit(body: => Unit) = {
* println("dummy text, printed before initialization of C")
* body // evaluates the initialization code of C
* }
* }
*
* class C extends Helper {
* println("this is the initialization code of C")
* }
*
* object Test extends App {
* val c = new C
* }
* }}}
*
* Should result in the following being printed:
* {{{
* dummy text, printed before initialization of C
* this is the initialization code of C
* }}}
So, just extend DelayedInit, follow the warnings you see in App (specifically, don't override args in your extending class), and you should be able to access them just as App does:
@deprecatedOverriding("main should not be overridden", "2.11.0")
def main(args: Array[String]) = {
this._args = args
//other stuff goes here as you like
}
However, if you do it like this, be aware that it is deprecated, like it says there, so you run the risk of losing the functionality in future versions of Scala.
Upvotes: 3