Side-effecting nullary methods are discouraged: suggest defining as ... for IntelliJ - scala

I executed this code block in a IntelliJ worksheet (Community Edition EAP 15#143.379.11 with Scala plugin 1.9.4 on JDK 1.8.0_66) ,
class Plant
class Fruit extends Plant
class Apple extends Fruit
class Box[T <: Fruit](var item: T) {
def get: T = item
def replace(item: T): Unit = this.item = item
}
val appleBox = new Box(new Apple)
println(appleBox.get) // error
and IntelliJ reported this error during worksheet compilation and stopped,
Error:(22, -59) side-effecting nullary methods are discouraged: suggest defining as `def get$$instance$$res0()` instead
println(appleBox.get);//
^
How do I disable this error or change it to warning and let me continue? I am using IntelliJ . Thanks

To avoid an error just remove println, Scala Worksheet will print the object for you.
val appleBox = new Box(new Apple)
appleBox.get
appleBox: Box[Apple] = Box#4109bbc4
res0: Apple = Apple#6e2e3a8b
PS: I do not get the error you are reporting in the latest EAP Scala Plugin (1.9.272)

Related

what is '???' in Scala?

I'm learning Scala using IntelliJ IDE.
When I subs class Element and override contents method, IDE provided default implementation for contents method with definition ???
Below code from the book Programming in Scala, 3rd edition
Element
abstract class Element {
def contents: Array[String]
def height = contents.length
def width = if (height == 0) 0 else contents(0).length
}
ArrayElement
class ArrayElement(cont: Array[String]) extends Element {
override def contents: Array[String] = ??? // impl provided by IDE
}
I don't see any issues in running the program but when I access the method I get below exception
Exception in thread "main" scala.NotImplementedError: an implementation is missing
at scala.Predef$.$qmark$qmark$qmark(Predef.scala:284)
at org.saravana.scala.ArrayElement.contents(ScalaTest.scala:65)
Can someone explain what is ??? and use of it?
??? is designed as a placeholder and is a method defined in Predef (which is automatically imported by default)
It's definition is
def ??? : Nothing = throw new NotImplementedError
So it has return type Nothing and all it does is throw NotImplementedError. This definition allows it to used as a placeholder implementation for methods you defined but haven't implemented yet but still want to be able to compile your program.
Nothing is a subtype of every type, which makes ??? a valid implementation no matter what type is expected.

Why is the Scala compiler giving me an error when passing a Kotlin sealed class into a constructor?

I have a sealed class, written in Kotlin:
sealed class Schema {
class RecordSchema(val fields: List<Field>): Schema()
class ArraySchema(val elementSchema: Schema): Schema()
...
}
And another class that takes RecordSchema as a parameter:
class Enrichment(config: Config, val schema: RecordSchema) { ... }
In Scala I have a class that, among other things, get an instance of the RecordSchema and then create an instance of the Enrichment.
object Job {
def main(args: Array[String]): Unit = {
/// some initializing of resources... and then...
val recordSchema = schemas.getSchema(id) // type is Schema.RecordSchema
val enrichment = Enrichment(config, recordSchema) // this is where scalac errors out
}
}
The scala compiler ends up printing this error message:
Error:(52, 62) type mismatch;
found : com.companyname.enricher.schemas.com.companyname.enricher.schemas.com.companyname.enricher.schemas.
required: com.companyname.enricher.schemas.(some other)com.companyname.enricher.schemas.com.companyname.enricher.schemas.
val enrichment = new Enrichment(config, recordSchema)
If I cast recordSchema using asInstanceOf I get another, not so useful, error:
Error:(52, 62) type mismatch;
found : com.companyname.enricher.schemas.Schema.RecordSchema
required: com.companyname.enricher.schemas.com.companyname.enricher.schemas.
val enrichment = new Enrichment(config, recordSchema.asInstanceOf[RecordSchema])
Overall, I have no idea why this is happening. If I make the constructor take the parent class as a parameter rather than nested class, it compiles just fine (which is my workaround for now). If I do the same type of thing, except having written the sourcecode in Java rather than Kotlin, this error does not happen. I am using Java 1.8, Kotlin 1.0.4, Scala 2.11.8.
UPDATE:
demonstrated bug here:
https://github.com/mjburghoffer/scala-kotlin-innerclass-bug/tree/master
Looks like Kotlin generates different number of classes for this case. I compiled Java and Kotlin sources and found that Java has additional file ParentSealedJava$1.class. Bytecode of Parent and Sealed classes in Java and Kotlin pretty the same (i inspect bytecode using javap -c), so i think Scala compiler relies somehow on this missing file in Kotlin.

Why Scala Enumeration does not work in Apache Zeppelin but it works in maven

Enumeration works as expected when I use it in a maven project(with the same Scala version).
object t {
object DashStyle extends Enumeration {
val Solid,ShortDash = Value
}
def f(style: DashStyle.Value) = println(style)
def main(args: Array[String]) = f(DashStyle.Solid)
}
But when it runs in Apache Zeppelin(Zeppelin 0.6, Spark 1.6, Scala 2.10, Java 1.8)
object DashStyle extends Enumeration {
val Solid,ShortDash = Value
}
def f(style: DashStyle.Value) = println(style)
f(DashStyle.Solid)
It reports the following error even it says found and required type is exactly the same
<console>:130: error: type mismatch;
found : DashStyle.Value
required: DashStyle.Value
f(DashStyle.Solid)
Why and how should I use it?
I figured out the trick to solve this issue.
In Apache Zeppelin (or Scala REPL). In order to use Enumeration or sealed&object, it should be wrapped in object but not directly define on the root scope.
The reason why it works in maven is that I already put it into an object.
Define enumeration in an object in a Zeppelin paragraph
object t {
object DashStyle extends Enumeration {
val Solid,ShortDash = Value
}
def f(style: DashStyle.Value) = println(style)
}
Then use it in a Zeppelin paragraph
import t._
f(DashStyle.Solid)

Is there anyway to create a new Scala object from a Java Class

I have a number of use cases for this, all around the idea of interop between existing Java libraries and new Scala Code. The use case I've selected is the easiest I think.
Use Case:
I working on providing a JUnit Runner for some scala tests (so that I can get my lovely red / green bar in Eclipse)
The runner needs to have a constructor with a java class as a parameter. So in Scala I can do the following:
class MyRunner(val clazz: Class[Any]) extends Runner {
def getDescription(): Description
def run(notifier: RunNotifier)
}
When I use either
#RunWith(MyRunner)
object MyTestObject
or
#RunWith(MyRunner)
class MyTestClass
then the runner is indeed instantiated correctly, and is passed a suitable class object
Unfortunately what i want to do now is to "get hold of" the object MyTestObject, or create a MyTestClass, which are both Scala entities. I would prefer to use Scala Reflection, but I also want to use the standard Junit jar.
What I have done
The following Stackover flow questions were educational, but not the same problem. There were the nearest questions I could find
How to create a TypeTag manually?
Any way to obtain a Java class from a Scala (2.10) type tag or symbol?
Using Scala reflection with Java reflection
The discussion on Environments, Universes and Mirrors in http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html was good, and the similar documents on other scala reflection also helped. Mostly through it is about the Scala reflection.
I browsed the Scaladocs, but my knowledge of Scala reflection wasn't enough (yet) to let me get what I wanted out of them.
Edit:
As asked here is the code of the class that is being created by reflection
#RunWith(classOf[MyRunner])
object Hello2 extends App {
println("starting")
val x= "xxx"
}
So the interesting thing is that the solution proposed below using the field called MODULE$ doesn't print anything and the value of x is null
This solution works fine if you want to use plan old java reflection. Not sure if you can use scala reflection given all you will have is a Class[_] to work with:
object ReflectTest {
import collection.JavaConversions._
def main(args: Array[String]) {
val fooObj = instantiate(MyTestObject.getClass())
println(fooObj.foo)
val fooClass = instantiate(classOf[MyTestClass])
println(fooClass.foo)
}
def instantiate(clazz:Class[_]):Foo = {
val rm = ru.runtimeMirror(clazz.getClassLoader())
val declaredFields = clazz.getDeclaredFields().toList
val obj = declaredFields.find(field => field.getName() == "MODULE$") match{
case Some(modField) => modField.get(clazz)
case None => clazz.newInstance()
}
obj.asInstanceOf[Foo]
}
}
trait Foo{
def foo:String
}
object MyTestObject extends Foo{
def foo = "bar"
}
class MyTestClass extends Foo{
def foo = "baz"
}

scala case class private apply method( repl bug ?)

in Scala2.10.0 REPL
Welcome to Scala version 2.10.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_13).
Type in expressions to have them evaluated.
Type :help for more information.
scala> case class A private(i:Int)
defined class A
scala> A(1)
res0: A = A(1)
But if compile
$ scala -version
Scala code runner version 2.10.0 -- Copyright 2002-2012, LAMP/EPFL
$ cat Main.scala
package foo
case class A private (i:Int)
object Main extends App{
println(A(1))
}
$ scalac Main.scala
Main.scala:6: error: constructor A in class A cannot be accessed in object Main
println(A(1))
^
one error found
A.apply(1) is compile error.
is this Scala2.10.0 REPL bug?
FYI Scala2.9.2 REPL is following
Welcome to Scala version 2.9.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_13).
Type in expressions to have them evaluated.
Type :help for more information.
scala> case class A private(i:Int)
defined class A
scala> A(1)
<console>:10: error: constructor A in class A cannot be accessed in object $iw
A(1)
^
This definitely looks like a REPL bug.
Note that the constructor is correctly marked as private (in other words, new A(1) does not compile, as expected), it is only the factory (A.apply) that is wrongly public.
I see... You think you're calling the constructor when you write A(1). You're not. You're calling the factory added for you in the automatically generated (public) companion object and its public apply method.
Addendum
My day to be repeatedly wrong…
In the 2.10.0 REPL:
scala> object REPL { case class CC1 private(i: Int); val cc1_1 = CC1(23) }
<console>:7: error: constructor CC1 in class CC1 cannot be accessed in object REPL
object REPL { case class CC1 private(i: Int); val cc1_1 = CC1(23) }
The REPL has one huge semantic difference w.r.t. the ordinary compiler.
Consider what it means to be able to do this:
scala> val v1 = 23
v1: Int = 23
scala> val v1 = 42
v1: Int = 42
Could you do that in compiled Scala code? Of course not, it would be a prohibited double definition.
How does the REPL do this? In effect every line you enter is in a progressively more nested scope. The appearance of redefinition is actual shadowing. It's as if you did this:
object REPL1 {
val v1 = 23
object REPL2 {
val v1 = 42
object REPL3 {
// Next REPL line here...
}
}
}
So, how do you get companions? Put an explicit object (or other scope-forming construct) around them. And remember, no blank lines. The REPL will stop accepting input for a given "line" or "block" when you do.