Cannot run a simple application in Scala - scala

Given the following code:
import scala.io.Source
object Demo {
def func():Unit = {
for ( line <- Source.fromFile("C:\Users\Hen\Scala_workspace\Itay\src\Demo.scala").getLines() ) {
println(line)
}
}
def main(args: Array[String]): Unit = {
//var x=args(0).toInt;
func();
}
}
Why is the pathname marked as a compilation error?
Eclispe won't let me run it

Try triple quotes around your path, so that scala will not interpret \ + char as special characters:
"""C:\Users\Hen\Scala_workspace\Itay\src\Demo.scala"""

Related

run object scala in databricks

I am trying to execute sample code on databricks in scala. It is an object.
object Main {
def main(args: Array[String]) {
val res = for (a <- args) yield a.toUpperCase
println("Arguments: " + res.toString)
}
}
When I run on databricks; it says 'object defined main'. I am not sure how to execute it now or what is the code to execute it. Please help.
What you are working with is kind of scala REPL. Basically "main" function does not have any significance over there. Having said that you can run your function as follows
object Main {
def main(args: Array[String]) {
val res = for (a <- args) yield a.toUpperCase
println(res)
println("Arguments: " + res.toString)
}
}
Main.main(Array("123","23123"))
As is you can call Object Main's main method.
You can call the main method in the Main object as follows:
val args: Array[String] = Array("test1", "test2", "test3")
Main.main(args)
What you have in your main method won't print what you expect, which I assume is the values contained in the res array. To accomplish that you would need to change it to something like the following:
object Main {
def main(args: Array[String]): Unit = {
val res = for (a <- args) yield a.toUpperCase
println("Arguments: " + res.mkString(" "))
}
}

scala AST - what IS a string constant literal and how do I find out?

Consider the following snippet
object Main {
def main(args:Array[String]): Unit ={
import Debugger.debug
debug("Hello World")
val x = 0
debug(x)
debug(1)
}
}
I want this to print
Hello World
x = 0
1
by making use of a macro:
import scala.language.experimental.macros
import scala.reflect.macros._
object Debugger {
val doDebug = true
def debug(v : Any) :Unit = macro implDebug
def implDebug(c:blackbox.Context)(v:c.Expr[Any]): c.Expr[Unit] ={
import c.universe._
if(doDebug) {
v match {
case Literal(Constant(_)) => reify{println(v.splice)}
case _ =>
println(v.tree)
println(v.tree.getClass.getName)
val rep = show(v.tree)
val repTree = Literal(Constant(rep))
val repExpr = c.Expr[String](repTree)
reify{
println(repExpr.splice + " = " + v.splice)
}
}
}
else reify{}
}
}
This outputs (compile + run):
[sbt compile bla bla]
"Hello World"
scala.reflect.internal.Trees$Literal
x
scala.reflect.internal.Trees$Ident
1
scala.reflect.internal.Trees$Literal
[info] Running Main
"Hello World" = Hello World
x = 0
1 = 1
so ... apparently, "Hello World" is a literal but doesn't match the literal pattern (also tried case Literal(_) with equally unsatisfying results).
Why? And what do I need to match instead?
Your implDebug method is accepting a c.Expr[Any], which is a wrapper for a c.Tree. Literal(Constant(...)) is the correct matcher for a literal tree value, but since you want to be matching on the tree, you should use v.tree match {...} instead.

What is the best way to get the name of the caller class in an object?

I could get this working using this:
scala> object LOGGER {
| def warning(msg: String)(implicit className:String) = {
| className
| }
| }
defined object LOGGER
scala> class testing {
| lazy implicit val className = this.getClass.getName
| def test = LOGGER.warning("Testing")
| }
defined class testing
scala> val obj = new testing()
obj: testing = testing#11fb4f69
scala> obj.test
res51: String = testing <=======
scala> class testing2 {
| lazy implicit val className = this.getClass.getName
| def test = LOGGER.warning("Testing")
| }
defined class testing2
scala> val obj2 = new testing2()
obj2: testing2 = testing2#2ca3a203
scala> obj2.test
res53: String = testing2 <=====
I also tried using Thread.currentThread.getStackTrace in the object LOGGER but couldn't get it to print the calling class testing in the warning function.
Any other ways to do this?
Dynamic variable
One way to do it is DymamicVariable
import scala.util.DynamicVariable
object LOGGER {
val caller = new DynamicVariable[String]("---")
def time = new Date().toString
def warning(msg: String) = println(s"[${caller.value} : $time] $msg")
}
trait Logging {
def logged[T](action: => T) = LOGGER.caller.withValue(this.getClass.getName)(action)
}
class testing extends Logging {
def test = logged {
//some actions
LOGGER.warning("test something")
//some other actions
}
}
val t = new testing
t.test
will print something like
[testing : Wed Nov 25 11:29:23 MSK 2015] test something
Or instead of mixing in Logging you can use it directly
class testing {
def test = LOGGER.caller.withValue(this.getClass.getName) {
//some actions
LOGGER.warning("test something")
//some other actions
}
}
Macro
Another more powerfull, but more complex to support approach is to build some simple macro
You could define in other source, preferrably in other subproject
import scala.reflect.macros.blackbox.Context
import scala.language.experimental.macros
class LoggerImpl(val c: Context) {
import c.universe._
def getClassSymbol(s: Symbol): Symbol = if (s.isClass) s else getClassSymbol(s.owner)
def logImpl(msg: Expr[String]): Expr[Unit] = {
val cl = getClassSymbol(c.internal.enclosingOwner).toString
val time = c.Expr[String](q"new java.util.Date().toString")
val logline = c.Expr[String](q""" "[" + $cl + " : " + $time + "]" + $msg """)
c.Expr[Unit](q"println($logline)")
}
}
object Logger {
def warning(msg: String): Unit = macro LoggerImpl.logImpl
}
Now you don't need to change the testing class:
class testing {
def test = {
//some actions
Logger.warning("something happen")
//some other actions
}
}
And see desired output.
Thsi could be very-perfomant alternative to runtime stack introspection
I use this technique in my custom classloader project to get the name of the first class up the stack not in my package. The general idea is copied from the UrlClassloader.
String callerClassName="";
StackTraceElement[] stackTrace=Thread.currentThread().getStackTrace();
for (int i=1; i < stackTrace.length; i++) {
String candidateClassName=stackTrace[i].getClassName();
if(!candidateClassName.startsWith("to.be.ignored") &&
!candidateClassName.startsWith("java")){
callerClassName=candidateClassName;
break;
}
}
The approach has it's drawbacks since it only gets the name of the class, not the actual class or even better the object.

What are the ways to convert a String into runnable code?

I could not find how to convert a String into runnable code, for instance:
val i = "new String('Yo')"
// conversion
println(i)
should print
Yo
after the conversion.
I found the following example in another post:
import scala.tools.nsc.interpreter.ILoop
import java.io.StringReader
import java.io.StringWriter
import java.io.PrintWriter
import java.io.BufferedReader
import scala.tools.nsc.Settings
object FuncRunner extends App {
val line = "sin(2 * Pi * 400 * t)"
val lines = """import scala.math._
|var t = 1""".stripMargin
val in = new StringReader(lines + "\n" + line + "\nval f = (t: Int) => " + line)
val out = new StringWriter
val settings = new Settings
val looper = new ILoop(new BufferedReader(in), new PrintWriter(out))
val res = looper process settings
Console println s"[$res] $out"
}
link: How to convert a string from a text input into a function in a Scala
But it seems like scala.tools is not available anymore, and I'm a newbie in Scala so i could not figure out how to replace it.
And may be there are just other ways to do it now.
Thanks !
You can simple execute your code contained inside String using Quasiquotes(Experimental Module).
import scala.reflect.runtime.universe._
import scala.reflect.runtime.currentMirror
import scala.tools.reflect.ToolBox
// TO compile and run code we will use a ToolBox api.
val toolbox = currentMirror.mkToolBox()
// write your code starting with q and put it inside double quotes.
// NOTE : you will have to use triple quotes if you have any double quotes usage in your code.
val code1 = q"""new String("hello")"""
//compile and run your code.
val result1 = toolbox.compile(code1)()
// another example
val code2 = q"""
case class A(name:String,age:Int){
def f = (name,age)
}
val a = new A("Your Name",22)
a.f
"""
val result2 = toolbox.compile(code2)()
Output in REPL :
// Exiting paste mode, now interpreting.
import scala.reflect.runtime.universe._
import scala.reflect.runtime.currentMirror
import scala.tools.reflect.ToolBox
toolbox: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] = scala.tools.reflect.ToolBoxFactory$ToolBoxImpl#69b34f89
code1: reflect.runtime.universe.Tree = new String("hello")
result1: Any = hello
code2: reflect.runtime.universe.Tree =
{
case class A extends scala.Product with scala.Serializable {
<caseaccessor> <paramaccessor> val name: String = _;
<caseaccessor> <paramaccessor> val age: Int = _;
def <init>(name: String, age: Int) = {
super.<init>();
()
};
def f = scala.Tuple2(name, age)
};
val a = new A("Your Name", 22);
a.f
}
result2: Any = (Your Name,22)
scala>
To learn more about Quasiquotes :
http://docs.scala-lang.org/overviews/quasiquotes/setup.html
I found a simple solution using the ToolBox tool :
val cm = universe.runtimeMirror(getClass.getClassLoader)
val tb = cm.mkToolBox()
val str = tb.eval(tb.parse("new String(\"Yo\")"))
println(str)
This is printing:
Yo
The scala compiler (and the "interpreter loop") are available here. For example:
https://github.com/scala/scala/blob/v2.11.7/src/repl/scala/tools/nsc/interpreter/ILoop.scala
A compiled jar that has that class will be in your scala distribution under lib\scala-compiler.jar.
One way could be to take/parse that string code and then write it yourself in some file as Scala code. This way it would be executed by Scala compiler when you will call it.
An example: just like Scala is doing with Java. It takes this code and then convert it into Java by making use of main method.
object Xyz extends App {
println ("Hello World!")
}

How can i unit test console input in scala?

How can i unit test console input in scala with scalaTest.
Code under Test:
object ConsoleAction {
def readInput(in: InputStream): List[String] = {
val bs = new BufferedSource(in)(Codec.default)
val l = bs.getLines()
l.takeWhile(_!="").toList
}
def main(args: Array[String]) {
val l = ConsoleAction.readInput(System.in)
println("--> "+l)
}
}
I'd like to test the readInput method.
A one line input can be tested like that:
"Result list" should "has 1 element" in {
val input = "Hello\\n"
val is = new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8))
assert(ConsoleAction.readInput(is).size===1)
}
... but what is the way for multiline input?
input line 1
input line 2
thx
Your problem lies with how you're escaping your newline. You're doing "\\n" rather than "\n". This test should pass.
"Result list" should "has 2 elements" in {
val input = "Hello\nWorld\n"
val is = new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8))
assert(ConsoleAction.readInput(is).size===2)
}