Scala: "In-place" the trait Inheriting without "new" keyword - scala

I can't understand why a syntax error occurs in this code:
"T.scala" file:
trait T
"A.scala" file:
class A
object A {
def apply() = new A()
}
"other.scala" file:
val a = new A() with T // ok
val b = A() with T // syntax error ';' or newline expected
Can I create a new class instance with inheriting without using the new keyword?
I've not found anything about it.

A() translates to A.apply() which is a method that returns a new object and is not the same as new A().
You are essentially trying to do this (which will not work):
val b = A.apply()
val c = b with T
You can't use with on an object that has already been created.

Related

Unable to create companion class instance in companion object method

What's wrong with this code:
class Trivials(s:String){
private val x = 0
}
object Trivials {
def main(args: Array[String]): Unit = {
Trivials t = new Trivials("Trivials")
}
}
Both class and object are defined in same source file, hence they are companion.
Error message is as: 'Cannot resolve symbol t'
Wrong syntax (You are using Java syntax) for object creation. In case of Scala you need not mention the type in front of the variable t it will be automatically inferred.
Trivials t = new Trivials("Trivials")
Scala syntax
val t = new Trivials("Trivials")

Using Scala reflection to compile and load object

Given the following String:
"println(\"Hello\")"
It is possible to use reflection to evaluate the code, as follows.
object Eval {
def apply[A](string: String): A = {
val toolbox = currentMirror.mkToolBox()
val tree = toolbox.parse(string)
toolbox.eval(tree).asInstanceOf[A]
}
}
However, lets say that the string contains an object with a function definition, such as:
"""object MyObj { def getX="X"}"""
Is there a way to use Scala reflection to compile the string, load it and run the function? What I have tried to do has not worked, if anyone has some example code it is very appreciated.
It depends on how strictly you define the acceptable input string. Should the object always be called MyObj? Should the method always be called getX? Should it always be 1 method or can it be multiple?
For the more general case you could try to extract all method names from the AST and generate calls to each one. The following code will call every method (and returns the result of the last one) that takes 0 arguments and is not a constructor, in some object, not taking inheritance into account:
def eval(string: String): Any = {
val toolbox = currentMirror.mkToolBox()
val tree = toolbox.parse(string)
//oName is the name of the object
//defs is the list of all method definitions
val ModuleDef(_,oName,Template(_,_,defs)) = tree
//only generate calls for non-constructor, zero-arg methods
val defCalls = defs.collect{
case DefDef(_,name,_,params,_,_)
if name != termNames.CONSTRUCTOR && params.flatten.isEmpty => q"$oName.$name"
}
//put the method calls after the object definition
val block = tree :: defCalls
toolbox.eval(q"..$block")
}
And using it:
scala> eval("""object MyObj { def bar() = println("bar"); def foo(a: String) = println(a); def getX = "x" }""")
bar
res60: Any = x

Scala standalone object not getting recognized

I am creating a singleton object using script xyz.scala as follow :
object ChecksumCalculator {
def calcChecksum(s: String): Int = {
val cc = new ChecksumCalculator
for (c <- s)
cc.add(c.toByte)
cc.checksum
} }
When I run this as script as Scala xyz.scala ,
I am getting the error as :
01HW993798:scala tcssig$ scalac xyz.scala
xyz.scala:3: error: not found: type ChecksumCalculator
val cc = new ChecksumCalculator
^
one error found
Although I have declared the standalone object at the top, is it possible that my standalone object is not getting recognized.
Or is it due to some other error ?
In scala, singleton objects are instantiated on usage and guaranteed to be instantiated only once, hence providing strict "singleton" semantics.
Assuming that your object has method "add(b:Byte)" you could do:
CheckSumCalculator.add(c.toByte)
But given that we are in the scope of CheckSumCalculator, using this should be sufficient:
add(c.toByte)
That said, using a singleton object for mutable operations seems a bad idea.
It looks like that what you are looking for is to create instances of some class, but also have some facility method that can be called statically.
That construction has a name in Scala: A companion object
companion objects are defined by creating an object of the same name as some given class.
Translating that to this scenario, we would have:
class ChecksumCalculator {
def add(b:Byte) = ???
def checksum(): Int = ??? // or whatever type the checksum is
}
object ChecksumCalculator { // this is a companion object
def calcChecksum(s: String): Int = {
val cc = new ChecksumCalculator
s.foreach(c => cc.add(c.toByte))
cc.checksum()
}
}

Accessing to methods of case classes

Why I can't access to methods of case class inside method of ordinary class when I initiate case class instance without new keyword?
I.e. in the following code I get a compile-time error:
case class A() {
private var _g = 12
//getter-setter
def g = _g
def g_=(value : Int) = this._g = value
}
class B {
def someMethod = {
val aInstance = A
aInstance.g = 4; // compile time error. Why?
}
}
But if I add new keyword in aInstance declaration all work fine.
Error message is:
Cannot resolve symbol g
You need to make an instance of class A with A() (which calls apply on A). Otherwise you're referring to the companion object itself.
How about this? You did not define f and meant probably aInstance.
class B {
def someMethod = {
val aInstance = A
aInstance.g = 4
}
}

Scala reflection error: this is an inner module, use reflectModule on an InstanceMirror to obtain its ModuleMirror

Following up on this question, I'm trying to figure out how to call a method on an object. The relevant definitions are:
trait ThirdParty { def invoke = println("right") }
trait WeatherIcon { def invoke = println("wrong") }
class MyClass {
object objA extends ThirdParty
object objB extends WeatherIcon
}
I got a Symbol for objA like this:
import reflect.runtime.universe._
val stuff = typeOf[MyClass].members.filter(_.isValue).filter(_.typeSignature <:< typeOf[ThirdParty])
That returns an Iterable with a single element, so let's say:
val objASymbol = stuff.head.asModuleSymbol
I then tried, based on this other question, this:
val mirror = runtimeMirror(getClass.getClassLoader)
mirror.reflectModule(objASymbol)
Which resulted in the error message quoted on the subject:
java.lang.Error: this is an inner module, use reflectModule on an InstanceMirror to obtain its ModuleMirror
at scala.reflect.runtime.JavaMirrors$JavaMirror.reflectModule(JavaMirrors.scala:118)
at scala.reflect.runtime.JavaMirrors$JavaMirror.reflectModule(JavaMirrors.scala:60)
The problem is that I can't figure out what this error message is telling me to do!
You need to write runtimeMirror.reflect(<instance of MyClass>).reflectModule(objASymbol). Plain reflectModule won't do, because some reflective operations on objA (e.g. getting its instance) require an outer instance.
Unfortunately, your use case won't work even if you write it right, because M4 only supports static objects: https://issues.scala-lang.org/browse/SI-5498. We'll implement this before 2.10.0-final.