Why is the main function not running in the REPL?

我的梦境 提交于 2021-02-18 10:43:53

问题


This is a simple program. I expected main to run in interpreted mode. But the presence of another object caused it to do nothing. If the QSort were not present, the program would have executed.

Why is main not called when I run this in the REPL?

object MainObject{
  def main(args: Array[String])={
    val unsorted = List(8,3,1,0,4,6,4,6,5)
    print("hello" + unsorted toString)
    //val sorted = QSort(unsorted)
    //sorted foreach println
  }
}

//this must not be present

object QSort{
  def apply(array: List[Int]):List[Int]={
    array
  }
}

EDIT: Sorry for causing confusion, I am running the script as scala filename.scala.


回答1:


What's happening

If the parameter to scala is an existing .scala file, it will be compiled in-memory and run. When there is a single top level object a main method will be searched and, if found, executed. If that's not the case the top level statements are wrapped in a synthetic main method which will get executed instead.

This is why removing the top-level QSort objects allows your main method to run.

If you're going to expand this to a full program, I advise to compile and run (use a build tool like sbt) the compiled .class files:

scalac main.scala && scala MainObject

If you're writing a single file script, just drop the main method (and its object) and write the statements you want executed in the outer scope, like:

// qsort.scala
object QSort{
  def apply(array: List[Int]):List[Int]={
    array
  }
}

val unsorted = List(8,3,1,0,4,6,4,6,5)
print("hello" + unsorted toString)
val sorted = QSort(unsorted)
sorted foreach println

and run with: scala qsort.scala

A little context

The scala command is meant for executing both scala "scripts" (single file programs) and complex java-like programs (with a main object and a bunch of classes in the classpath).

From man scala:

   The  scala  utility  runs  Scala code using a Java runtime environment.
   The Scala code to run is specified in one of three ways:

      1.  With no arguments specified, a Scala shell starts and reads com-
          mands interactively.

      2.  With  -howtorun:object  specified, the fully qualified name of a
          top-level Scala object may be specified.  The object should pre-
          viously have been compiled using scalac(1).

      3.  With  -howtorun:script  specified,  a file containing Scala code
          may be specified.

If not explicitly specified, the howtorun mode is guessed from the arguments passed to the script.

When given a fully qualified name of an object, scala will guess -howtorun:object and expect a compiled object with that name on the path.

Otherwise, if the parameter to scala is an existing .scala file, -howtorun:script is guessed and the entry point is selected as described above.




回答2:


Any method of an object module can be run in REPL by explicitly specifying it and giving it the arguments it requires if any. For example:

scala> object MainObject{
     |   def main(args: Array[String])={
     |     val unsorted = List(9,3,1,0,7,5,9,3,11)
     |     print("sorted: " + unsorted.sorted)
     |   }
     |   def fun = println("fun here")
     | }
defined module MainObject

scala> MainObject.main(Array(""))
sorted: List(0, 1, 3, 3, 5, 7, 9, 9, 11)
scala> MainObject.fun
fun here

In some cases this can be useful for quick testing and troubleshooting.



来源:https://stackoverflow.com/questions/9877314/why-is-the-main-function-not-running-in-the-repl

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!