Run class in Scala IDE - eclipse

I just installed the Eclipse Scala IDE and imported some existing projects. However, when I want to run the classes (that contain a main def) via right click -> Run, I only get 'Run configurations...'. How can I run these Scala classes?
(I already checked that the 'Scala Nature' is added.)

You need to run an object not a class as noted by urban_racoons. so you can run either:
object MyApp{
def main(args: Array[String]): Unit = {
println("Hello World")
}
}
or
object MyApp extends App {
println("Hello World")
}
Scala can not run a class because the main method needs to be static. Which can only be created behind the scenes by the compiler from a singleton object in Scala. Create the object and "run as a Scala application" should appear in the "run" context sub menu as long as you have the Scala perspective open.
You can still access the programme's arguments using the App trait as in
object MyApp extends App {
println("The programme arguments are:")
args.foreach(println)
// the above is just shorthand for
// args.foreach(ar => println(ar))
}
It should also be noted that App is a trait. So it can be mixed in with other traits and any class, which makes it handy for rapid prototyping.

Related

Object extends App or Object + def main(...)? [duplicate]

What is the difference between
object Application extends App {
println("Hello World")
}
and
object Application {
def main(args: Array[String]): Unit = {
println("Hello World");
}
}
The App trait is a convenient way of creating an executable scala program. The difference to the main method altenative is (apart from the obvious syntactic differences) that the App trait uses the delayed initalization feature.
From the release notes for 2.9 (see http://www.scala-lang.org/old/node/9483 )
Objects inheriting the App trait instead make use of Scala 2.9’s delayed initialization feature to execute the whole body as part of an inherited main method.
Another new feature of the App scheme is that command line arguments are now accessible via the args value (which is inherited from trait App)
These two cases is not same on the scala scripting.
object extends App was not executed by "scala MyObject.scala" command,
but the object containing the main method was executed by "scala MyObject.scala" command.
Which was described as scala looking for object with main method for scripting.
When using REPL or scala workseet of Eclipse,
need to call MyObject.main(Array[String]()) explicitly for both cases.
This simple tip be helpful for beginner like me.
App trait is implemented using the [[DelayedInit]] functionality, which means that fields of the object will not have been initialized before the main method has been executed.

Cannot run scala in IntelliJ

I'm struggling with running Scala Hello World project using IntelliJ IDEA Scala plugin. The project is created without any problems but when I create function which should be run, the run button doesn't appear. I've got no idea why it doesn't work.
Version of IntelliJ - 2020.3.1 (Community Edition)
Version of Scala plugin 2020.3.18
I've created Scala/sbt project (I'd also tried Scala/IDEA)
Vanilla options (but I'd also tried other versions of JDK, Scala and sbt)
The run button is missing
My code is:
class Hello extends App {
println("Hello world")
}
I've tried creating Scala worksheet and It works.
When you extend App, it needs to be as object Main extends App, not class Main extends App.
See Scala 2.13 specification 9.5 (emphasis mine):
A program is a top-level object that has a member method main of type (Array[String])Unit
The main method of a program can be directly defined in the object, or it can be inherited. The scala library defines a special class scala.App whose body acts as a main method
As Suma mentioned in his answer, you should use object, and not class. The code of the Hello file should be:
object Hello {
def main(args: Array[String]): Unit = {
println("Hello world")
}
}
As stated in YOUR FIRST LINES OF SCALA. Please note that if you prefer to extend App, all of the statements will be executed, as stated in the last link:
The argument of the scala command has to be a top-level object. If that object extends trait scala.App, then all statements contained in that object will be executed; otherwise you have to add a method main which will act as the entry point of your program.
Which means you have another option:
object Hello extends App {
println("Hello world")
}
I have created a gif that shows an example.

Difference between using App trait and main method in scala

What is the difference between
object Application extends App {
println("Hello World")
}
and
object Application {
def main(args: Array[String]): Unit = {
println("Hello World");
}
}
The App trait is a convenient way of creating an executable scala program. The difference to the main method altenative is (apart from the obvious syntactic differences) that the App trait uses the delayed initalization feature.
From the release notes for 2.9 (see http://www.scala-lang.org/old/node/9483 )
Objects inheriting the App trait instead make use of Scala 2.9’s delayed initialization feature to execute the whole body as part of an inherited main method.
Another new feature of the App scheme is that command line arguments are now accessible via the args value (which is inherited from trait App)
These two cases is not same on the scala scripting.
object extends App was not executed by "scala MyObject.scala" command,
but the object containing the main method was executed by "scala MyObject.scala" command.
Which was described as scala looking for object with main method for scripting.
When using REPL or scala workseet of Eclipse,
need to call MyObject.main(Array[String]()) explicitly for both cases.
This simple tip be helpful for beginner like me.
App trait is implemented using the [[DelayedInit]] functionality, which means that fields of the object will not have been initialized before the main method has been executed.

How to use members with default (package) or private access level in REPL?

I was trying to add some interactivity to my test/debug cycle, so I tried playing around with my classes from the Scala REPL. This works great but has the disadvantage that I cannot access package- and private-level members, that can be tested from a unit test (if the test is in the same package).
Can I "set" the package "context" of the Scala REPL?
I guess I could use reflection to access the members, but that's so much typing it would defeat the purpose of using the REPL in the first place.
I assume the class you are testing are written in Java as you have to go out of your way to create package only member in Scala.
In short, it's not possible. Each line in the REPL is wrapped into it's own package, so it won't be allowed to access another package-only member from any other package. Even though there is an undocumented system property to change the default package name prefix used for wrapping, the package name is still generated automatically by incrementing a number:
$ scala -Xprint:parser -Dscala.repl.naming.line=foo.line
scala> val x = 1
[[syntax trees at end of parser]]// Scala source: <console>
package foo.line1 {
object $read extends scala.ScalaObject {
// snip ...
object $iw extends scala.ScalaObject {
// snip ...
object $iw extends scala.ScalaObject {
// snip ...
val x = 1
}
}
}
Assuming this is something you do often, what you could do is create a file that makes the reflection easy to use and then load it into the REPL using :load command.
Do you mean that you cannot access members defined in the package object? You can import these members using
import mypackage._
or simply access them using the prefixed form mypackage.mymember(...).

In Scala static value initialization does not appear to be happening before the main method is called

My Scala version:
Scala code runner version 2.9.0.1 -- Copyright 2002-2011, LAMP/EPFL
Given this code in a file named Static.scala:
object Main extends App {
val x: String = "Hello, World!"
override def main(args: Array[String]): Unit = {
println(x)
}
}
When I run:
scalac Static.scala && scala Main
I see:
null
instead of:
Hello, World!
I thought that x was a static because it was defined in an object, and that it would be initialized prior to the main method being called.
What am I doing wrong? Thanks!
This happens because of how you used the App trait. The App trait uses the DelayedInit feature which changes how the class body (including field initialization) is executed. The App trait includes a main method which executes the class body after binding the args field to the arguments to the program. Since you have overridden main this initialization is not happening. You should not provide a main method when using the App trait. You should either put the application code directly in the class body or not inherit from the App trait.
Try
lazy val x = "Hello World"
That should give you the results you're expecting.
You are not support to have a main method on an object extending App. If you do override it, you'd better understand how, exactly, DelayedInit works. In particular, objects extending App do not have static initialization -- that's the whole point of App.