Import statement:error:not found in Scala REPL - scala

I am new to scala. I have created a scala object containing a couple of methods. I am trying to invoke the method from Scala REPL but the import statement is not working.
This is the code I tried (It is in a default package):
object Hello extends App {
def sum(xs: List[Int]): Int = 0;
def max(xs: List[Int]): Int = 0;
}
For starting the Scala REPL, I opened the console and then did the following:
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Users\user>sbt
[info] Set current project to user (in build file:/C:/Users/user/)
> console
[info] Updating {file:/C:/Users/user/}user...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Starting scala interpreter...
[info]
Welcome to Scala version 2.10.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_2
2).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import Hello._
<console>:7: error: not found: value Hello
import Hello._
^
scala>
The project workspace and the project is created in E:/Work. Even I tried navigating to the project and then followed the same steps above but it gives the same error.
Please let me know how to make this import statement work from Scala REPL.

For project structure please refer to this page
Your dir tree should be something like
E:
|
`- Work
|
`- {PROJECT}
|
+- build.sbt
|
`- src
|
`- main
|
`- scala
|
`- Hello.scala
Next navigate to E:\Work\{Project} and from there run sbt and only then console and do all the work
Remember that your REPL will refer to classes that were compiled before console were executed.
Note that your project structure could be much simpler like
E:
|
`- Work
|
`- {PROJECT}
|
`- Hello.scala
But this is not recommended

you need to compile your project
exit the scala REPL, then from the shell prompt:
> sbt clean compile package
the compile task is a dependency on the sbt, so just sbt is the same as sbt compile, but i don't see a line in your console output that shows it compiled your project (it will begin with Compiling)
alternatively if you have no dependencies (which it looks like you don't) then you can just paste that code directly in the REPL session, and let the Scala REPL compile your code for you, like so:
scala> :paste
// paste your code in the REPL window
scala> ctrl-D

Related

Why ClassNotFoundException from sbt console but not Scala REPL

First I delete the .sbt from my home-directory, then I make an empty project directory, and in that directory I create a build.sbt file:
echo 'ThisBuild / scalaVersion := "3.1.3"' > build.sbt
Then I run sbt console and at the console prompt attempt the following Class.forname() invocation, which produces the following ClassNotFoundException:
[info] welcome to sbt 1.7.1 (Debian Java 11.0.16)
Welcome to Scala 3.1.3 (11.0.16, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.
scala> Class.forName("java.sql.Connection")
java.lang.ClassNotFoundException: java.sql.Connection
at dotty.tools.repl.AbstractFileClassLoader.findClass$$anonfun$1(AbstractFileClassLoader.scala:46
On the other hand, if I start the REPL with the plain-old scala command, then invoke the same forName() I see this:
Welcome to Scala 3.1.3 (11.0.16, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.
scala> Class.forName("java.sql.Connection")
val res0: Class[?] = interface java.sql.Connection
So the same forName() invocation elicits different behavior in the sbt console versus the Scala REPL: a ClassNotFoundException in the former versus returning an instance of the Class class in the latter.
The sbt console also produces that ClassNotFoundException with any of the following lines in the build.sbt file:
classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.AllLibraryJars
or
classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.ScalaLibrary
or even
classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat
What is it about sbt that causes the exception, and how can sbt be made to succeed?

Why can't scala find what sbt can?

With sbt everything is fine:
» sbt console
[info] Loading project definition from /repos/myrepo/project
[info] Set current project to bpavscan (in build file:/repos/myrepo/)
[info] Starting scala interpreter...
[info]
Welcome to Scala 2.11.8 (OpenJDK 64-Bit Server VM, Java 1.8.0_131).
Type in expressions for evaluation. Or try :help.
scala> import play.api.libs.json._
import play.api.libs.json._
scala>
But if I do it with the scala tool:
» scala
Welcome to Scala version 2.11.6 (OpenJDK 64-Bit Server VM, Java 1.8.0_131).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import play.api.libs.json._
<console>:7: error: not found: value play
import play.api.libs.json._
^
scala>
I need to run a simple script, which I usually do with:
scala myscript.scala
But since now my script has a play dependency, I can not run it with scala anymore, since scala does not find play.
I need to either:
Be able to load the play framework with the simple scala tool
Be able to run a simple script with sbt: sbt run runs my project, which I do not want. I want to run a simple script (to try out some simple things)
sbt console with load the same console/REPL as of scala but with additional loaded dependencies defined in build.sbt. So before loading the console, all the dependent libraries are added. And this is reason you could import play libraries while using sbt console.
On the other hand scala starts the console with the libraries inside scala-package of the system. Thus needs additional jars being included inside the package for importing. For the above case if play library jar was included in scala directory then import play.api.libs.json._ should have worked for scala console too.

Scala sbt jar allows import when class path is passed on command line, but not in REPL

I've built a small test jar with Scala and SBT. If I put the classpath argument on the Scala REPL command line, it imports the package perfectly. However if I get into the shell and then add the classpath, it does not recognize the import. Being new to Scala this confuses me so I hope someone can explain. I'll try to provide enough information without going overboard.
scala -cp configparser_2.10-1.0.jar
Welcome to Scala version 2.10.4 (OpenJDK 64-Bit Server VM, Java 1.7.0_75).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import com.oaktreepeak.util._
import com.oaktreepeak.util._
scala> val c = new OakConfig()
c: com.oaktreepeak.util.OakConfig = com.oaktreepeak.util.OakConfig#58d9a418
Now I'll wait and load the classpath to the jar after I'm in the shell:
scala
Welcome to Scala version 2.10.4 (OpenJDK 64-Bit Server VM, Java 1.7.0_75).
Type in expressions to have them evaluated.
Type :help for more information.
scala> :cp configparser_2.10-1.0.jar
Added '/home/*****/Dyn/projects/DynECT2/scala/common/ConfigParser/test-configs/configparser_2.10-1.0.jar'. Your new classpath is:
".:/home/*****/Dyn/projects/DynECT2/scala/common/ConfigParser/test-configs/configparser_2.10-1.0.jar"
Nothing to replay.
scala> import com.oaktreepeak.util._
<console>:7: error: object oaktreepeak is not a member of package com
import com.oaktreepeak.util._
^
scala>
Here is my build.sbt file:
name := "ConfigParser"
version := "1.0"
scalaVersion := "2.10.4"
organization := "com.oaktreepeak"
And the single Scala source file:
package com.oaktreepeak.util
import scala.io._
import scala.util.parsing.json._
class OakConfig {
var iRollupAfter: Int = -1;
def Load(sPath: String) {
val config = Source.fromFile(sPath).mkString
val json:Option[Any] =JSON.parseFull(config)
val map:Map[String,Any] = json.get.asInstanceOf[Map[String, Any]]
iRollupAfter = map.get("RollupAfter").get.asInstanceOf[Double].toInt
}
}
Anyone have any ideas or explanations?
Thanks
:cp was broken in Scala 2.10, and has been replaced with (a working) :require in Scala 2.11.
If you're new to Scala I would recommend using the latest, stable version of Scala, which currently is 2.11.6.
Also, as you're new to Scala, if you want to try things out from your project in the REPL (which is a great workflow) from sbt just run console, which will compile your code and give you REPL with all of Scala's classes, your projects classes and the classes for all your dependencies! No need to feed manually feed the REPL a classpath.

How can I get scala to work in the command line?

I run Windows 7.
I have java (a current enough version to run scala) and scala downloaded on my computer. I've set PATH so that when I type "scala" into the command prompt it sends me to the proper interface:
Welcome to Scala version 2.9.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_51)
Type in expressions to have them evaluated.
Type :help for more information
However I can't execute the command "scala" or "scalac" on my test files.
scala> scala Hello
(console):8: error: object Hello is not a member of package scala
This makes me think I'm in the wrong directory. The file Hello.scala is saved in the home directory that I set PATH to.
However I get a different issue when I try to compile code.
scala> scalac Hello.scala
(console):1: error: ';' expected but '.' found.
I actually got my test file to work at one point... but I wasn't actually IN scala.
C:\scala-2.9.1.final\bin> scala Hello.scala
Hello world!
I'm not really sure how to proceed from here. If anyone has any ideas of what may be wrong I would greatly appreciate input.
It appears that you're trying to run & compile programs from within the Scala REPL (read-evaluate-print loop - a kind of Scala interpreter) and you cannot do that in the REPL. The REPL allows you to type in Scala statements and see them execute immediately. (If you're not sure how you entered the REPL, you probably just entered the command scala from the command line.) The REPL is useful for testing ideas, and for experimenting with Scala. For example:
C:\some\path> scala
Welcome to Scala version 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_91).
Type in expressions for evaluation. Or try :help.
scala> println ("Hello!")
Hello!
scala> val x = 10
x: Int = 10
scala> val y = x * 5
y: Int = 50
scala> sys.exit
C:\some\path>
However, the REPL isn't what you would use to compile & run Scala programs - you need to do that from the command line (or from a tool such as sbt). If you want to run your program directly from the command line, without using the REPL (that is, without being in Scala, as you put it) then you would need to do the following:
Firstly, compile your program using scalac:
C:\some\path> scalac Hello.scala
If that succeeds, you can then run the program with the scala command (which looks for a Hello.class file):
C:\some\path> scala Hello
(Here C:\some\path is the location of the files Hello.scala & Hello.class.)
Alternatively, as you have already discovered, you can run your Scala program as a script in the REPL. You can do this from the command line as follows (note the addition of the filetype .scala after Hello compared to the command above):
C:\some\path> scala Hello.scala
or from within the REPL:
scala> :load Hello.scala
Hope this helps!
You don't have to issue scala command when you're inside REPL. If you want to execute code from that file, load it:
here is what I have in Foo.scala
println("I'm foo")
Now I'm starting the REPL (and as you can see scala> is a sign that you're ALREADY into REPL and can start execute raw scala code):
Welcome to Scala version 2.10.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_25).
Type in expressions to have them evaluated.
Type :help for more information.
scala> :load Foo.scala
Loading Foo.scala...
I'm foo

Predefine routine in scala sbt console?

I am recently writing scala, using sublimetext to write *.scala and run sbt in another window.
When I use sbt console to debug, every time I need to manually import packages and do routines.
It's really annoying to repeat copying codes again and again after I recompile and restart console.
I wonder is there a way to set a predefined environment to do it manually?
Another question I want to know is in console REPL can I auto complete lines by the initial characters? For example in python IDLE one can use Alt+p to search history. It's really convenience.
Initial commands
You could add this line to your build.sbt:
initialCommands in console := "import scalaz._, Scalaz._"
Result:
$ sbt console
[info] Starting scala interpreter...
[info]
import scalaz._
import Scalaz._
Welcome to Scala version 2.10.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_45).
Type in expressions to have them evaluated.
Type :help for more information.
scala>
REPL auto complete
You could tap Tab key to get limited auto complete:
scala> List(1, 2, 3)
res0: List[Int] = List(1, 2, 3)
scala> res0.ap
First Tab - auto complete and options:
scala> res0.apply
apply applyOrElse
Second Tab - method signature:
scala> res0.apply
def apply(n: Int): A
History
You could use Ctrl+R to search in history (including history from previous REPL sessions). Use addition Ctrl+R to get next result.
Also probably worth noting is that you can load scripts into the repl, too:
$ cat > guessing.txt
import scala.util.Random.nextInt
def guess() {
val r = nextInt()
println("I randomly picked %d.".format(r))
}
$ sbt console
scala> :load guessing.txt
Loading guessing.txt...
import scala.util.Random.nextInt
guess: ()Unit
scala> guess
I randomly picked -630907258.
:help is your friend.