summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2011-02-21 13:51:58 +0000
committerMartin Odersky <odersky@gmail.com>2011-02-21 13:51:58 +0000
commit9779036af852c57874b5e0c820eb1cbe7b11e163 (patch)
treedc1bbbfd5f3bc84be44ecad66edfafee2618e60c /src/library
parentebec4165292d9a8ec9b01b47ebd287964d205fd3 (diff)
downloadscala-9779036af852c57874b5e0c820eb1cbe7b11e163.tar.gz
scala-9779036af852c57874b5e0c820eb1cbe7b11e163.tar.bz2
scala-9779036af852c57874b5e0c820eb1cbe7b11e163.zip
Moved delayedInit Application to App; reinstant...
Moved delayedInit Application to App; reinstantiated 2.8.1 Application and deprecated it.
Diffstat (limited to 'src/library')
-rw-r--r--src/library/scala/App.scala66
-rw-r--r--src/library/scala/Application.scala109
2 files changed, 127 insertions, 48 deletions
diff --git a/src/library/scala/App.scala b/src/library/scala/App.scala
new file mode 100644
index 0000000000..59c6fccec3
--- /dev/null
+++ b/src/library/scala/App.scala
@@ -0,0 +1,66 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+package scala
+
+import scala.compat.Platform.currentTime
+import scala.collection.mutable.ListBuffer
+
+/** The `App` trait can be used to quickly turn objects
+ * into executable programs. Here is an example:
+ * {{{
+ * object Main extends App {
+ * Console.println("Hello World: " + (arguments mkString ", "))
+ * }
+ * }}}
+ * Here, object `Main` inherits the `main` method of `App`.
+ *
+ * `args` returns the current command line arguments as an array.
+ *
+ * @author Martin Odersky
+ * @version 2.1, 15/02/2011
+ */
+trait App extends DelayedInit {
+
+ /** The time when the execution of this program started, in milliseconds since 1
+ * January 1970 UTC. */
+ val executionStart: Long = currentTime
+
+ /** The command line arguments passed to the application's `main` method.
+ */
+ protected def args: Array[String] = _args
+
+ private var _args: Array[String] = _
+
+ private val initCode = new ListBuffer[() => Unit]
+
+ /** The init hook. This saves all initialization code for execution within `main`.
+ * This method is normally never called directly from user code.
+ * Instead it is called as compiler-generated code for those classes and objects
+ * (but not traits) that inherit from the `DelayedInit` trait and that do not themselves define
+ * a `delayedInit` method.
+ * @param body the initialization code to be stored for later execution
+ */
+ override def delayedInit(body: => Unit) {
+ initCode += (() => body)
+ }
+
+ /** The main method.
+ * This stores all argument so that they can be retrieved with `args`
+ * and the executes all initialization code segements in the order they were
+ * passed to `delayedInit`
+ * @param args the arguments passed to the main method
+ */
+ def main(args: Array[String]) = {
+ this._args = args
+ for (proc <- initCode) proc()
+ if (util.Properties.propIsSet("scala.time")) {
+ val total = currentTime - executionStart
+ Console.println("[total " + total + "ms]")
+ }
+ }
+}
diff --git a/src/library/scala/Application.scala b/src/library/scala/Application.scala
index 352f8ee3d6..2060b509b8 100644
--- a/src/library/scala/Application.scala
+++ b/src/library/scala/Application.scala
@@ -1,71 +1,84 @@
/* __ *\
** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL **
+** / __/ __// _ | / / / _ | (c) 2002-2010, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
-
-
-
package scala
import scala.compat.Platform.currentTime
-import scala.collection.mutable.ListBuffer
-/** The `Application` trait can be used to quickly turn objects
- * into executable programs. Here is an example:
- * {{{
- * object Main extends Application {
- * Console.println("Hello World: " + (arguments mkString ", "))
- * }
- * }}}
- * Here, object `Main` inherits the `main` method of `Application`.
+/** <p>
+ * The <code>Application</code> trait can be used to quickly turn objects
+ * into executable programs, but is <em>not recommended</em>.
+ * Here is an example:
+ * </p><pre>
+ * <b>object</b> Main <b>extends</b> Application {
+ * Console.println("Hello World!")
+ * }
+ * </pre>
+ * <p>
+ * Here, object <code>Main</code> inherits the <code>main</code> method
+ * of <code>Application</code>. The body of the <code>Main</code> object
+ * defines the main program. This technique does not work if the main
+ * program depends on command-line arguments (which are not accessible
+ * with the technique presented here).
+ * </p>
+ * <p>
+ * It is possible to time the execution of objects that inherit from class
+ * <code>Application</code> by setting the global <code>scala.time</code>
+ * property. Here is an example for benchmarking object <code>Main</code>:
+ * </p><pre>
+ * java -Dscala.time Main
+ * </pre>
+ * <p>
+ * In practice the <code>Application</code> trait has a number of serious
+ * pitfalls:
+ * </p>
+ * <ul>
+ * <li> Threaded code that references the object will block until static
+ * initialization is complete. However, because the entire execution of an
+ * <code>object</code> extending <code>Application</code> takes place during
+ * static initialization, concurrent code will <em>always</em> deadlock if
+ * it must synchronize with the enclosing object.</li>
+ * <li>As described above, there is no way to obtain the
+ * command-line arguments because all code in body of an <code>object</code>
+ * extending <code>Application</code> is run as part of the static initialization
+ * which occurs before <code>Application</code>'s <code>main</code> method
+ * even begins execution.</li>
+ * <li>Static initializers are run only once during program execution, and
+ * JVM authors usually assume their execution to be relatively short.
+ * Therefore, certain JVM configurations may become confused, or simply fail to
+ * optimize or JIT the code in the body of an <code>object</code> extending
+ * <code>Application</code>. This can lead to a significant
+ * performance degradation.</li>
+ * </ul>
*
- * `arguments` returns the current command line arguments as an array.
- *
- * Note: The use of Application was discouraged prior to 2.9 because
- * application code would be run in the object constructor. This is no longer true.
- * Application code is now stored and run in the main method. As a consequence,
- * extending `Application` is now recommended over implementing `main` explicitly.
+ * It is recommended to use the `App` trait instead.
+ * <pre>
+ * <b>object</b> Main {
+ * <b>def</b> main(args: Array[String]) {
+ * //..
+ * }
+ * }
+ * </pre>
*
- * @author Martin Odersky
- * @version 2.0, 14/12/2010
+ * @author Matthias Zenger
+ * @version 1.0, 10/09/2003
*/
-trait Application extends DelayedInit {
+@deprecated("use App instead")
+trait Application {
/** The time when the execution of this program started, in milliseconds since 1
* January 1970 UTC. */
val executionStart: Long = currentTime
- /** The command line arguments passed to the application's `main` method.
- */
- protected def arguments: Array[String] = args
-
- private var args: Array[String] = _
-
- private val initCode = new ListBuffer[() => Unit]
-
- /** The init hook. This saves all initialization code for execution within `main`.
- * This method is normally never called directly from user code.
- * Instead it is called as compiler-generated code for those classes and objects
- * (but not traits) that inherit from the `DelayedInit` trait and that do not themselves define
- * a `delayedInit` method.
- * @param body the initialization code to be stored for later execution
- */
- override def delayedInit(body: => Unit) {
- initCode += (() => body)
- }
-
- /** The main method.
- * This stores all argument so that they can be retrieved with `arguments`
- * and the executes all initialization code segements in the order they were
- * passed to `delayedInit`
+ /** The default main method.
+ *
* @param args the arguments passed to the main method
*/
- def main(args: Array[String]) = {
- this.args = args
- for (proc <- initCode) proc()
+ def main(args: Array[String]) {
if (util.Properties.propIsSet("scala.time")) {
val total = currentTime - executionStart
Console.println("[total " + total + "ms]")