Run/Debug Config on IDEA 13 for Scala Application - scala

complete stranger/newbie question, sorry to bother you:
I want to run a scala project in IDEA 13 (on Mac OSX), there is no run/debug configuration. I tried some options, however I don't know what to choose (and what should happen, then).
I tried:
Scala Console
Scala Script
Scala Test
Specs2
Choosing Scala Console: something happens, but I get no message box from my showMessage(message = "Hello World") messagebox. (It did work in Eclipse, so far).
Scala Script: I suppose this is meant for single lines of code, not an app, is that?
Specs2: Error in options-dialog: Specs2 is not specified. What is spec2? What should I enter and where? Error while debugging: no main class detected. OK, there is none, I can see that.
Any other option I should use, or normally is used?
Would any help appreciate very much!
This is my (very simple) scala app. Somehow, I'd expect to get an message box while running from IDEA.
import swing._
import swing.Dialog._
import scala.swing.event.ButtonClicked
object HW {
def main(args: Array[String]): Unit = {}
showMessage(message = "Hello World")
}
by the way: the closest tread I've found was this, but it didn't really help, looked too different:
How to run scala code on Intellij Idea 11?

Just use "Application". You have to select a main class and a module.
In terms of your example, I recommend not mixing a def main with a "free" standing constructor body. Also, Swing code should be called only from the event dispatch thread (Swing.onEDT). The easiest for desktop applications is to extend trait SwingApplication which handles that for you:
import swing._
import swing.Dialog._
object HW extends SwingApplication {
def startup(args: Array[String]): Unit =
showMessage(message = "Hello World")
}

Related

Is it possible in Scala to have functions/methods inside a package{}?

I am currently following Miss Wiem Zine's article (specifically on ZIO): Make your program testable
but I couldn't get pass the
package console {
def println(line: String): ZIO[Console, Nothing, Unit] =
ZIO.accessM(_.console println line)
val readLine: ZIO[Console, Nothing, String] =
ZIO.accessM(_.console.readLine)
}
I've read in alvin alexander's page, but it's all about scoping.
I tried it in intellij, but it complains.
Could it be a
package object console {
...
}
instead of package console {}?
Or is that a scala 3 thing? Or am I doing something wrong?
In Scala 2, we have a concept of package objects. There are examples here: https://www.scala-lang.org/docu/files/packageobjects/packageobjects.html.
I think code snippet from "Wiem Zine's article" is missing object keyword, so you are right it should be: package object console, since the whole example is on ZIO and Scala 2.x. There is no ZIO for Scala 3 yet, as far as I know :-)
#Thilo is also right that Scala 3 allows us to use top-level definitions right in the file without necessity to wrap into a block. Until Scala 3, one can use package object to get common package code.

Not getting a result from SBTCookbook code from Play Framework

Play Framework has, as part of their guides, this bit: https://www.playframework.com/documentation/2.5.x/SBTCookbook#Hooking-into-Plays-dev-mode
It describes the creation of a .scala file in the project/ folder, which allows you to execute some processes before starting the application in DEV mode.
So, I thought I'd try something simple like this:
import play.sbt.PlayRunHook
import sbt._
object Hello {
def apply(base: File): PlayRunHook = {
object HelloThere extends PlayRunHook {
override def beforeStarted(): Unit = {
Process("echo hello", base).run
}
}
HelloThere
}
}
File is saved as Hello.scala
But I'm not seeing anything in the console after running activator run. Am I doing something wrong? I did go to the localhost:9000 url in the browser to see if that caused the compilation of anything more, but no results from that either.
Using Play 2.5.8
I have no experience in Scala, only Java. Though there doesn't seem anything wrong with the code. It's just a copy paste with the object name replaced and the process text replaced.

eclipse does not treat a scalatest flatspec as junit test

here is my test case , while i right click the file eclipse doest not show any run as junit test option. I try to manual create run configuration but does not take any sense.
scala version:2.8.1 scalatest:1.3 eclipse:3.6.2
package org.jilen.cache.segment
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec
import org.scalatest.matchers.ShouldMatchers
#RunWith(classOf[JUnitRunner])
class RandomSegmentSpec extends FlatSpec with ShouldMatchers {
val option = SegmentOptions()
"A Simple Segment" should "contains (douglas,lea) after put into" in {
val segment = RandomSegment.newSegment(option)
segment.put("douglas", "lea")
segment("douglas") should be("lea")
}
it should "return null after (douglas,lea) is remove" in {
val segment = RandomSegment.newSegment(option)
segment.put("douglas", "lea")
segment -= ("douglas")
segment("douglas") should equal(null)
}
it should "contains nothing after clear" in {
val segment = RandomSegment.newSegment(option)
segment.put("jilen", "zhang")
segment.put(10, "ten")
segment += ("douglas" -> "lea")
segment += ("20" -> 20)
segment.clear()
segment.isEmpty should be(true)
}
}
I've encountered this seemingly randomly, and I think I've finally figured out why.
Unfortunately the plugin doesn't yet change package declarations when you move files, nor the class names when you rename files. (Given you can put multiple classes in one file, the latter will likely never be done.) If you are used to the renamings being done automagically in Eclipse, like I am, you're bound to get caught on this.
So... check carefully the following:
the package declaration in your Scala file matches the Eclipse package name
the name of the test class in the Scala file matches the name of the Scala file
I just ran into this, fixed both, and now my test runs!
This is a known problem with the Eclipse IDE for Scala. I'm currently working on the plugin for this. Watch this space.
I found Scalatest to be very bad at integrating with Eclipse (running the tests from eclipse showed that it ran them - but they would not pass or fail, but simply show up as passive blank boxes).
For some reason I could NOT get it to work after 3 hours of trying things!
Finally I tried specs2 - and it worked (Scala 2.9, Junit4 and Eclipse 3.6)!
They have a great doc here:
http://etorreborre.github.com/specs2/guide/org.specs2.guide.Runners.html#Runners+guide
Since I don't care which testing framework to use, I will try Specs2 purely from the convenience point of view.

Internal scala compilation. Working with interactive.Global

I am trying to retrieve the AST from scala souce file. I have simplified the code (only relevant code) to following.
trait GetAST {
val settings = new Settings
val global = new Global(settings, new ConsoleReporter(settings))
def getSt = "hello" //global.typedTree(src, true)
}
object Tre extends GetAST {
def main(args:Array[String])
{
println(getSt.getClass)
println("exiting program")
}
}
The above code compiles fine and runs fine. But the problem is the program does not exit. The prompt is not displayed after printing "exiting program". I have to use ^c to exit.
Any idea what the problem might be
I believe Michael is correct, the compiler uses Threads and therefore the JVM doesn't just exit.
The good news is that interactive.Global mixes in interactive.CompilerControl trait whose askShutdown method you can call at the end of your main to let the program exit.
Without knowing what Settings, Global and ConsoleReporter are nobody can give you an exact answer. I would guess that at least one of them is creating a thread. The JVM waits until all threads are done (or all running are deamon threads). See here.
I would bet if you comment out the settings and global lines it will exit as expected.

How to reload a class or package in Scala REPL?

I almost always have a Scala REPL session or two open, which makes it very easy to give Java or Scala classes a quick test. But if I change a class and recompile it, the REPL continues with the old one loaded. Is there a way to get it to reload the class, rather than having to restart the REPL?
Just to give a concrete example, suppose we have the file Test.scala:
object Test { def hello = "Hello World" }
We compile it and start the REPL:
~/pkg/scala-2.8.0.Beta1-prerelease$ bin/scala
Welcome to Scala version 2.8.0.Beta1-prerelease
(Java HotSpot(TM) Server VM, Java 1.6.0_16).
Type in expressions to have them evaluated.
Type :help for more information.
scala> Test.hello
res0: java.lang.String = Hello World
Then we change the source file to
object Test {
def hello = "Hello World"
def goodbye = "Goodbye, Cruel World"
}
but we can't use it:
scala> Test.goodbye
<console>:5: error: value goodbye is not a member of object Test
Test.goodbye
^
scala> import Test;
<console>:1: error: '.' expected but ';' found.
import Test;
There is an alternative to reloading the class if the goal is to not have to repeat previous commands. The REPL has the command
:replay
which restarts the REPL environment and plays back all previous valid commands. (The invalid ones are skipped, so if it was wrong before, it won't suddenly work.) When the REPL is reset, it does reload classes, so new commands can use the contents of recompiled classes (in fact, the old commands will also use those recompiled classes).
This is not a general solution, but is a useful shortcut to extend an individual session with re-computable state.
Note: this applies to the bare Scala REPL. If you run it from SBT or some other environment, it may or may not work depending on how SBT or the other environment packages up classes--if you don't update what is on the actual classpath being used, of course it won't work!
Class reloading is not an easy problem. In fact, it's something that the JVM makes very difficult. You do have a couple options though:
Start the Scala REPL in debug mode. The JVM debugger has some built-in reloading which works on the method level. It won't help you with the case you gave, but it would handle something simple like changing a method implementation.
Use JRebel (http://www.zeroturnaround.com/jrebel). JRebel is basically a super-charged class reloading solution for the
JVM. It can handle
member addition/removal, new/removed classes, definition changes, etc. Just about the only thing it can't handle is changes in class hierarchy (adding a super-interface, for
example). It's not a free tool, but they do offer a complementary license which is limited to Scala compilation units.
Unfortunately, both of these are limited by the Scala REPL's implementation details. I use JRebel, and it usually does the trick, but there are still cases where the REPL will not reflect the reloaded class(es). Still, it's better than nothing.
There is an command meet you requirement
:load path/to/file.scala
which will reload the scala source file and recompiled to classes , then you can replay you code
This works for me....
If your new source file Test.scala looks something like this...
package com.tests
object Test {
def hello = "Hello World"
def goodbye = "Goodbye, Cruel World"
}
You first have to load the new changes into Scala console (REPL).
:load src/main/scala/com/tests/examples/Test.scala
Then re-import the package so you can reference the new code in Scala console.
import com.tests.Test
Now enjoy your new code without restarting your session :)
scala> Test.goodbye
res0: String = Goodbye, Cruel World
If the .scala file is in the directory where you start the REPL you can ommit the full path, just put :load myfile.scala, and then import.