Scala worksheet does not evaluate object in IntelliJ IDEA 2016.2 - scala

This very simple worksheet content demonstrates the issue:
object Test {
println("This does not print!")
add(5, 6)
}
println("This however prints!")
add(5, 6)
def add(a: Int, b: Int): Int = a + b
Results from the above worksheet content are:
defined module Test
This however prints!
res0: Unit = ()
res1: Int = 11
add: add[](val a: Int,val b: Int) => Int
Based on JetBrains official website Scala Worksheets example and every other reliable resource I've found (like Martin Odresky's own examples in Functional Programming in Scala course), I would expect the contents of object Test to execute. My software is:
OS X El Capitan
IntelliJ IDEA 2016.2
SBT Plugin 1.8.0
SBT Version 0.13.12
Scala Plugin 2016.2.1
Scala Version 2.11.8

I was able to evaluate the Scala work sheet by changing the Scala worksheet settings.
change run type to plain (original it was REPL)
You can get to settings by clicking the settings icon on the Scala worksheet.

The scala worksheet executes the contents of the object test{....} if all the code is inside that object. If there is some code outside the object, it will just define that Test object (and not run it).
object Test {
println("This does not print!")
def add(a: Int, b: Int): Int = {print("Sum:" + a + b); a + b}
add(2, 2)
}
// defined the above Test object
Test // executes the Test object

I think this is what you want:
object Test {
println("This does not print!")
add(5, 6)
println("This however prints!")
add(5, 6)
def add(a: Int, b: Int): Int = a + b
}
How the worksheet works is, that if you define an object and nothing defined outside the object scope, it will execute it as Test extends App. Which is what the intellij page displays
If you have any statement outside the object scope, it is then treated as any other object and compiler will initialize it like anything else. This is what you are experiencing.

Related

Sum of list element in scala is not executable : error. How to fix?

I am not able to execute or **▶ button is not clickable in intelleiJ ** the sum function in following two ways. Please help me to identify the mistakes in both.
object Main{
def sum1(xs : List[Int]): Int = {
xs.filter(_ > 0).sum // am i missing return word here ?
}
def sum2(xs: List[Int]): Unit = {
val mx = xs.filter(_ > 0).sum // is it ok to have return in a variable ?
println(mx)
}
Main.sum1(List(1,2))
Main.sum2(List(1,2,3,4))
}
For Intellij, unless you code from within a Scala Worksheet where you can execute execute code without an entry point, in any normal application, you require an entry point to your application.
In Scala 2 you can do this in 2 ways. Either define the main method yourself inside an object definition, which is the conventional way:
object Main {
def main(args: Array[String]): Unit = {
// code here
}
}
Or - have your object definition extend the App trait, which provides the main method for you, so you can start writing code directly inside:
object Main extends App {
// code here
}
This is a bit cleaner, and one nested-levels less.
In Scala, statements are called expressions, because they generally return the value of the last expression, if the last expression is not an assignment. This code:
def sum1(xs: List[Int]): Int =
xs.filter(_ > 0).sum
Is a syntactic sugar for this:
def sum1(xs: List[Int]): Int = {
return xs.filter(_ > 0).sum
}
Because braces are optional if the code has only 1 expression, and will return the value of the last expression by default. So even though you can write code both ways, you'll get the warning Return keyword is redundant, because you'll never need to use it explicitly.
Also, you don't need to write Main.sum1(...) from within Main. You can omit the object:
object Main extends App {
def sum1(xs: List[Int]): Int =
xs.filter(_ > 0).sum
def sum2(xs: List[Int]): Unit = {
val mx = xs.filter(_ > 0).sum
println(mx) // 10
}
println(sum1(List(1, 2))) // 3
sum2(List(1, 2, 3, 4))
}
For Scala 3, things get simpler. The recommended way is to annotate a method with the #main annotation to mark it as the entry point in your program. This method ca either be defined at the top-level, or inside an object definition, and it's name does not matter anymore:
#main def hello() =
// code here
While Scala 3 still supports the App trait from Scala 2, it has now become deprecated and it's functionality has been limited, so if your program needs to cross-build between both Scala 2 and Scala 3 versions, it’s recommended to stick with the basic way of explicitly define a main method inside an object definition with an Array[String] argument instead:
object MyMain:
def main(args: Array[String]) =
// code here
Note, curly braces become optional in Scala 3 in favor of the cleaner Python-style indentation.

Understanding methods Vs functions in scala

I am learning the difference between methods and functions. I am following this link
http://jim-mcbeath.blogspot.co.uk/2009/05/scala-functions-vs-methods.html
The article says if you compile the following code:
class test {
def m1(x:Int) = x+3
val f1 = (x:Int) => x+3
}
We should get two files
1. test.class
2. test$$anonfun$1.class
But I do not get it. Secondly the example says if we execute the following command in REPL, we will get the below
scala> val f1 = (x:Int) => x+3
f1: (Int) => Int = <function>
But I get only this
scala> val f1 = (x:Int) => x+3
f1: Int => Int = $$Lambda$1549/1290654769#6d5254f3
Is it because we are using a different version? Please help.
Scala 2.11 and earlier versions behave as shown in the blog post.
The behavior changed in Scala 2.12. Scala now uses the lambda support that was added to version 8 of the JVM, so it doesn't need to emit the extra .class file. As a result, the .jar files produced by 2.12 are usually a lot smaller.
As a side effect of this, Scala can't override toString anymore, so you see the standard JVM toString output for lambdas.

Scala worksheet can not resolve class name - IntelliJ IDEA

I am following along with a lecture, the lecturer is using Eclipse but I am using IntelliJ IDEA Community Edition 15.0.6, and the code on a Scala worksheet named rationals.scala is as follows
object rationals{
val x = new Rational(1,2)
x.numer
x.denom
}
//noinspection ScalaPackageName
class Rational(x: Int, y: Int) {
def numer = x
def denom = y
}
The Scala worksheet worksheet will not compute and there is a warning (not error) associated with the class definition that reads
Package names doesn't correspond to directories structure, this may
cause problems with resolve to classes from this file
Also, and this is odd but maybe significant, IDEA flags numer and denom as typos.
Any guidance? thx
The problem isn't with the name matching directory structure, the actual problem is that you have multiple definitions in the worksheet which it doesn't like. If you declare the class inside the object, then it'll compute properly:
object rationals {
class Rational(x: Int, y: Int) {
def numer = x
def denom = y
}
val x = new Rational(1,2)
x.numer
x.denom
}
#Yuval Itzchakov #MaxWen
If you reference Rational.scala outside the worksheet, then you have to make sure to tick the Make project box the first time you run it.
Eclipse and IntelliJ worksheets don't work the same. –

Print out Scala worksheet results in interactive mode in IntelliJ

For some reason, intermediate values aren't being printed out in the REPL console (right hand side of the worksheet)
For instance, this is what I have:
object test {
val obj = new MyObject(1)
obj.value
}
class MyObject(x: Int) {
def value = x
}
In the REPL results, I only get the following:
defined module test
.
.
.
defined class MyObject
However, I don't get any of the intermediate results, such as when I evaluate x.value
I would expect something like:
> MyObject#14254345
> 1
after x.value
Any reason why this isn't printing out?
What ended up working for me in this case (and this might be particular to IntelliJ 14, since I've seen it working the other way in Eclipse) is I added the class inside the object block, like this:
object test {
val obj = new MyObject(1)
obj.value
class MyObject(x: Int) {
def value = x
}
}
This forced the REPL instance inside the worksheet to auto-evalute the result and print them out on the right hand side.
To make it work like it does in Eclipse, turn on "eclipse compatibility" mode. This worked for me using IntelliJ IDEA 2016.
Preferences > Language & Frameworks > Scala > Worksheet
Then, check the Use "eclipse compatibility" mode checkbox.
Sorry, I don't have enough reputation to comment so I have to write it here.
If you want to get the result you want, maybe you can try like this.
scala> :paste
// Entering paste mode (ctrl-D to finish)
object test {
val obj = new MyObject(1)
println(obj.value)
}
class MyObject(x: Int) {
def value = x
}
// Exiting paste mode, now interpreting.
defined object test
defined class MyObject
scala> test.obj
1
res4: MyObject = MyObject#1cd072a9
when you paste the code, test and MyObject are not initialized, certainly you can not get any print.
test.obj will cause test to be initialized so will obj, meantime, obj.value also get evaluated. However, if you don't something about it(like print), it's just a pure expression.

var_dump() in Scala

Is there any convenient way to dump all members of a specified object in Scala,
like var_dump(), PHP function?
As mentioned in "How to Dump/Inspect Object or Variable in Java" (yes, I know, the question is about Scala):
Scala (console) has a very useful feature to inspect or dump variables / object values :
scala> def b = Map("name" -> "Yudha", "age" -> 27)
b: scala.collection.immutable.Map[java.lang.String,Any]
scala> b
res1: scala.collection.immutable.Map[java.lang.String,Any] = Map((name,Yudha), (age,27))
But if you want more details, you can give REPL Scala Utils a try, in order to get a "Easier object inspection in the Scala REPL"
So I've written a utility for use on the Scala REPL that will print out all of the "attributes" of an object.
(Note: "I" being here: Erik Engbrecht, also on BitBucket)
Here's some sample usage:
scala> import replutils._
import replutils._
scala> case class Test(a: CharSequence, b: Int)
defined class Test
scala> val t = Test("hello", 1)
t: Test = Test(hello,1)
scala> printAttrValues(t)
hashCode: int = -229308731
b: int = 1
a: CharSequence (String) = hello
productArity: int = 2
getClass: Class = class line0$object$$iw$$iw$Test
That looks fairly anti-climatic, but after spending hours typing objName to see what's there, and poking at methods, it seems like a miracle.
Also, one neat feature of it is that if the class of the object returned is different from the class declared on the method, it prints both the declared class and the actual returned class.
You might want to look at ToStringBuilder in commons-lang, specificly ToStringBuilder.reflectionToString().
In compiled code, the nicest way is usually just to declare your type as a case class, then use the generated toString method.
Anything else subclassing Product should be just as easy (currently just tuples)
Failing that, write your own toString method, it's usually trivial enough...