I have some code:
object Main extends App
{
val NameTemplate = """^([A-Za-z]+)_(\d+)\.png""".r
override def main (args:Array[String])
{
// Why is NameTemplate null here?
}
}
Why is NameTemplate
not initialized within the main method?
If you are using App
trait, then you don't need to override main
method - just write your code in the body of the object
:
object Main extends App {
val NameTemplate = """^([A-Za-z]+)_(\d+)\.png""".r
println(NameTemplate)
val NameTemplate(name, version) = args(0)
println(name + " v" + version)
}
It works because App
trait extends DelayedInit trait which has very special initialization procedure. You can even access arguments with args
, as shown in the example.
You still need to write main
method if you don't want to extend App
, but in this case it will work as expected:
object Main {
val NameTemplate = """^([A-Za-z]+)_(\d+)\.png""".r
def main(args: Array[String]) {
println(NameTemplate)
val NameTemplate(name, version) = args(0)
println(name + " v" + version)
}
}
The DelayedInit
trait (which App
extends) causes rewriting of intialisation code to execute within a special delayedInit()
method. This would then normally be invoked by main
. Since you are overriding main
, however, the delayedInit()
code is never being invoked, and as such your value is not being initialised.
As @tenshi explains, you can get around this either by not extending App
or by moving your main code into the body of your Main
object.