9

When I use the scala App trait, I can't get println to work.

This simple example prints as expected,

object HelloWorld {
  def main(args: Array[String]) {
    println("Hello, world!")
  }
}

But once I introduce the trait it does not,

object HelloWorld extends App {
  println("Hello, world!")
}

I get no errors but nothing prints to the console.

James McMahon
  • 48,506
  • 64
  • 207
  • 283

3 Answers3

10

Did you compile it first (running scalac HelloWorld.scala)? See this comment: http://www.scala-lang.org/node/9483#comment-40627

Edited to add more explanation: The first version actually was compiled. Scala files without an explicit main method are run uncompiled as scripts. That means that for your second version, the commands in the file are run sequentially, as though they had been entered into the interpreter--so, the object HelloWorld is created, but no method is called on it. There's more information about Scala as a scripting language here (scroll to Step 5): http://www.artima.com/scalazine/articles/steps.html

  • Strange. That seems like an odd limitation of the interpreter. Is there any explanation why I need to compile the class to get it to work? Do traits just not work in the interpreter? – James McMahon Jun 22 '12 at 00:53
  • 1
    And traits do work in the interpreter, but App is kind of a special case. It's often presented as "App wraps the code inside its implementing object in a main method," but that's not really it--rather, it sticks that code into something called delayedInit, which gets called when the main method is called rather than when the object is created, which is normally when bare code inside an object declaration is called. – Kelsey Gilmore-Innis Jun 22 '12 at 01:11
  • 1
    No problem--there's a more involved description of some of the potential pitfalls with Scala initialization in Chapter 4 of Josh Suereth's new book Scala in Depth, if you get insatiably curious about it :) – Kelsey Gilmore-Innis Jun 22 '12 at 01:14
  • @James, @Kelsey, It's compiled in both cases - how can it not be... the JVM runs on bytecode, not text. If you don't declare an outer object and run it as a script, your commands get wrapped up in a temporary object and compiled / run - but unlike if you run `scalac`, the .class files aren't saved to disk. Someone at some point decided that if your script consists of a single object with a `main` method, instead of wrapping it, it would just compile that object and run it. Not doing the same for `App` seems like an oversight, but it's not behaviour you should be relying on anyway, IMO. – Luigi Plinge Jun 22 '12 at 14:49
  • @LuigiPlinge, good point. The script is "interpreted" the same way code run in the Scala "interpreter" works--it's compiled as a temporary object and the .class files aren't saved. – Kelsey Gilmore-Innis Jun 22 '12 at 15:39
5

Add a line

object HelloWorld extends App {
  /* code */
}

HelloWorld.main(args)

at the end of your file.

The Class defines the method but it need to be called too.

A. Rabus
  • 489
  • 5
  • 13
-1

According to http://www.scala-lang.org/api/current/scala/App.html

you want to do

object Main extends App {
 Console.println("Hello World: " + (args mkString ", "))
}
placeybordeaux
  • 2,138
  • 1
  • 20
  • 42