Scala doesn't import from manually created package - scala

I'm using Scala with Ubuntu.
There are two files
File a.scala:
package ptest { class A() { def p = println ("A") } }
File b.scala
package ptest { import ptest.A ; class B() { def p = {print("B"); A.p} }
}
Compiling b.scala delivers an error:.
$ scalac a.scala
$ scalac b.scala
b.scala:2: error: A is not a member of ptest
although A.class is stored correct in dictionary ptest.
What is wrong?

You must explicitly put A.class on the classpath:
scalac -classpath . b.scala
(Replace . with the directory that contains A.class if it isn't in the current directory)
The next issue you have is import ptest.A, which doesn't do anything useful and produces a warning. There is no need to import members of the package you are in.
A.p produces an error. A.p means to invoke p on the value A, but no value A exists at that point. There is a class A, but you can't access class members without first creating an instance of that class.

Related

Adding unit test to a legacy Scala project in IntelliJ

I have a legacy Scala project to work with using maven as build tool.
Initially there is core code only under folder structure src/main/scala/ with package x.y.z and a file Main.scala with code as:
object Main {
def cube(x: Int) = {
x * x * x
}
}
There are no tests for the code. So I manually added a folder structure as test/scala under src.
Then I copied the package as for core code, ie x.y.z and added MainTest.scala with test code as:
class MainTest extends FunSuite {
test("Main.cube") {
assert(Main.cube(3) === 27)
}
}
Running test gives error as:
Error:(8, 12) not found: value Main
assert(Main.cube(3) === 27)
Why do I get this error?
For below project structure MainTest.scala and Main.scala are in the same package x.y.z therefore no package import is required, However MainTempTest.scala and Main.scala are in different package therefore an explicit import has to be done import x.y.z.Main
src
-main
--scala
---x.y.z
----Main.scala
-test
--scala
---MainTempTest.scala
---x.y.z
----MainTest.scala

Unable to declare functor type that takes zero parameters?

I'm trying to make a type definition for the function type () => Unit, I use this signature quite a bit for cleanup callback functions, and I'd like to give them more meaningful names.
I've tried the following, which I think should be correct syntax, but it doesn't compile:
package myPackage
import stuff
type CleanupCallback = () => Unit
trait myTrait ...
class mObject ...
Why doesn't it compile? And what is the correct syntax?
The compilation error is: expected class or object definition
You can't declare type alias out of class/trait/object scope. But you can declare it in package object as follows:
package object myPackage {
type CleanupCallback = () => Unit
}
It will be visible for all classes in myPackage.
Also you can import it in other classes which belong to other packages:
import myPackage.CleanupCallback
trait MyTrait {
def foo: CleanupCallBack
}
IDEA plugin supports creation of package objects, another version is (suppose you don't have IDEA plugin):
Create file package.scala in your package. The file must contain:
package object packageName { // name must match with package name
// ...
}

Handing Case Class Exceptions and Compiling them

I am trying to get these two classes to link up.
PatientMonitorExceptions.scala
abstract class PatientMonitorExceptions extends Exception
case class InvalidHeartRate (str:String) extends PatientMonitorExceptions
Here is my main.scala that I am trying to compile with the following line:
main.scala
import gasguru.patient.PatientMonitor
import gasguru.patient.Patient
import gasguru.patient.exceptions.InvalidHeartRate
object Main extends App {
val p = new Patient("snyder","brad");
val v = p.vitalSigns
val pm = new PatientMonitor(p);
p.vitalSigns.heartRate = 160;
println("The patient's heart rate is: " + p.vitalSigns.heartRate + " bpm");
try { pm checkHeartRate v.heartRate
}
catch {
case InvalidHeartRate(x) => println(x);
case _ => println("Something else");
}
}
I am running: scala main.scala to compile this
error: error while loading InvalidHeartRate, Missing dependency 'class InvalidHeartRate', required by ./gasguru/patient/exceptions/InvalidHeartRate.class
What does this error message mean?
When main.scala references InvalidHeartRate, it is referring to the companion object created for your case class InvalidHeartRate, and invoking the unapply method on it to do the match. The InvalidHeartRate object is dependent on the InvalidHeartRate case class being in the classpath. The error message occurred because even though the companion object's .class file (InvalidHeartRate$.class) could be found, the .class file for the case class itself is missing (InvalidHeartRate.class). I would suggest deleting all your .class files and recompiling.

Scala package object constructor

When and how is the Scala Package object constructor called?
I have two classes:
Package.scala
package my;
package object entities {
//Some initialization code in constructor
}
Classy.scala
package my.entities;
case class Classy {
}
I am trying to have the entities constructor to have already been executed by the time an object of Classy is created.
The package object is translated into a normal java class file called package.class IIRC. From then on I assume it behaves like any normal Java class, thus it is loaded and instantiated when it is first referenced. In Scala, that means you need to define some method or val in the package object, then access it from outside. In your case, you may try calling it from the constructor of Classy, or from the code which instantiates Classy.
Update
OK, here is some code I ran to test what I described above:
// package.scala
package some
package object pkg {
println("package created!")
def func() { println("func called") }
}
// C.scala
package some.pkg
class C {
println("created C")
}
// G.scala
package some.pkg
object G {
println("creating G")
func()
println("created G")
}
// PackageTester.scala
package some.pkg
object PackageTester extends App {
val c = new C
val g = G
}
And the output is:
created C
creating G
package created!
func called
created G
Which proves that Scala package objects are created lazily, only when they are actually referenced. And in fact the same is true for "normal" Scala objects, as demonstrated by G above.

Program works when run with scala, get compile errors when try to compile it with scalac

I am testing the code below, does a basic database query. It works fine when I run it from the CLI using "scala dbtest.scala", but gives me compile errors when I try to compile it with scalac :
[sean#ibmp2 pybackup]$ scalac dbtest.scala
dbtest.scala:5: error: expected class or object definition
val conn_str = "jdbc:mysql://localhost:3306/svn?user=svn&password=svn"
^
dbtest.scala:8: error: expected class or object definition
classOf[com.mysql.jdbc.Driver]
^
dbtest.scala:11: error: expected class or object definition
val conn = DriverManager.getConnection(conn_str)
^
dbtest.scala:12: error: expected class or object definition
try {
^
four errors found
import java.sql.{Connection, DriverManager, ResultSet};
import java.util.Date
// Change to Your Database Config
val conn_str = "jdbc:mysql://localhost:3306/svn?user=xx&password=xx"
// Load the driver
classOf[com.mysql.jdbc.Driver]
// Setup the connection
val conn = DriverManager.getConnection(conn_str)
try {
// Configure to be Read Only
val statement = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)
// Execute Query
val rs = statement.executeQuery("SELECT * FROM backup")
// Iterate Over ResultSet
var svnFiles = Set[String]()
while (rs.next) {
val repos = rs.getString("repos")
val lm = rs.getDate("lastModified")
val lb = rs.getDate("lastBackedup")
if (lm.getTime() > lb.getTime()) {
println(repos + " needs backing up")
svnFiles += repos
}
else {
println(repos + " doesn't need backing up")
}
}
println(svnFiles)
}
finally {
conn.close
}
You need either a class, object, or trait at the top level to make it a legal source to compile. scala interpreter expects definitions and expressions, whereas scalac expects something that can turn into Java .class files.
//imports here
object DbTest {
def main(args: Array[String]) {
// your code here
}
}
Create a file called HelloWorld.scala, and enter the following:
object HelloWorld {
def main(args: Array[String]){
println("Hello World")
}
}
To compile the example, we use scalac, the Scala compiler. scalac works like most compilers: it takes a source file as argument, maybe some options, and produces one or several object files. The object files it produces are standard Java class files.
From the command line, run:
scalac HelloWorld.scala
This will generate a few class files in the current directory. One of them will be called HelloWorld.class, and contains a class which can be directly executed using the scala command.
Once compiled, a Scala program can be run using the scala command. Its usage is very similar to the java command used to run Java programs, and accepts the same options. The above example can be executed using the following command, which produces the expected output:
Now run:
scala HelloWorld.scala
Now "Hello World", will be printed to the console.
After researching this functionality, I found an article, which explains this in detail, and posted that information here on SO to help programmers understand this aspect of Scala development.
Source: http://docs.scala-lang.org/tutorials/scala-for-java-programmers.html