Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala App val initialization in main method

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?

like image 306
Lenar Avatar asked Jan 31 '12 12:01

Lenar


2 Answers

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)
    }

}
like image 63
tenshi Avatar answered Nov 12 '22 11:11

tenshi


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.

like image 34
Submonoid Avatar answered Nov 12 '22 09:11

Submonoid