Trying to implement a Circular Enumeration in Scala - scala

Below is the trait that I would like to use
trait CircularEnumeration extends Enumeration {
class CircularVal extends Val {
def next(): Value = {
apply((id + 1) % values.size)
}
}
protected override final def Value: CircularVal = new CircularVal;
///////////////////////////////////////////////////////////////////////////
def nextValue(value: Value) = {
//first way
val nextIndex = values.toSeq.indexOf(value) + 1;
val value_nomath = if (nextIndex >= values.size) {
values.toSeq(0);
}
else {
values.toSeq(nextIndex);
}
//second way
val value_withmath = this((value.id + 1) % values.size);
assert(value_nomath == value_withmath);
value_withmath;
}
}
You can see that I already have tried two ways, and both have failed.
In the first the usage would be something like this:
MyEnumeration(index).next
and this would return me the next value of this enumeration
In the second the usage would be like that:
MyEnumeration.nextValue(MyEnumeration(index))
and once again this would return the next value
but in both occasions I have issues of which type is which. Because inside the trait the Value is actually CircularEnumeration.Value while inside the class which has this trait tha Value is MyEnumeration.Value
Any ideas?

I believe I can get it to work with the following changes - modify the return type of nextValue:
def nextValue(value: Value): CircularEnumeration.this.Value = {
and the last line (returned value) to:
value_withmath.asInstanceOf[CircularEnumeration.this.Value]
Then, defining MyEnumeration as:
scala> object MyEnumeration extends CircularEnumeration {
| type MyEnumeration = Value
| val Zero, One, Two, Three, Four = Value
| }
defined module MyEnumeration
we get:
scala> MyEnumeration.nextValue(MyEnumeration(3))
res0: MyEnumeration.Value = Four
scala> MyEnumeration.nextValue(MyEnumeration(4))
res1: MyEnumeration.Value = Zero

Related

Scala constructor overloading parameter is not taking effect

I'm trying to understand what's wrong with the way I'm implementing constructor overloading. I want to add a constructor that accepts an argument count, in a class that has a member with the same name.
The idea is to have count calculated off of one of the default constructor parameters, unless it is passed through the overload constructor. I show the code later.
To convince myself this can work, I constructed a quick and simple test:
import org.scalatest.FunSuite
class ConstructorOverloadTest extends FunSuite {
test("Overload parameter shadows class member") {
val actual = new TestME(200).length
200 === actual
1 !== actual
}
class TestME(name:String) {
val length = name.length
def this(length:Int) = {
this("*")
}
}
}
The test passes as expected. Which leads me to understand that the overload constructor parameter length shadows/replaces the class member length.
But when I do the same in another class, the class member is not shadowed/replaced.
class MyClass(input1: Array[Float], input2: Array[Byte], input3: Array[Float]) {
val count = input2.length
val index = doSomething()
def this(count: Int) = {
this(Array(), Array(), Array())
}
def printCount() = {
if (this.count == 0)
println("ZERO")
else
println("OTHER")
}
}
When I use this class as follows
val myInstance = new MyClass(200)
myInstance.printCount()
I expect it to print OTHER to the screen. Instead, it prints ZERO.
Why?
There appears to be something wrong with your test. new TestME(200).length returns 1, indicating that the constructor param does not in fact override length.
class TestME(name:String) {
val length = name.length
def this(length:Int) = {
this("*")
}
}
println(new TestME(200).length)
1
Per summerbulb's comments:
The test's assertions should be wrapped in assert:
// Closer to correct...
assert(200 === actual)
assert(1 !== actual)
Actual and expected values should be passed in that order:
// Correct!
assert(actual === 200)
assert(actual !== 1)

Scala: How do I set a generic Trait?

I can't set up this generic trait whose parametrized forms can be consumed by a common class/object/method. I have tried different +|-|_ combinations :-)
Update: The first comment below shows that this can work if the Wrapper is also parametrized. Can a non-parametrized Wrapper do the job? Can an object Wrapper do the job? Can some magic combination of +|-|_ and all that give me the same desired result with a non-parametrized Wrapper or object?
case class OldStuff(name: String)
case class NewStuff(id: Int)
trait Poster[T] {
def translate(i: Int):T
}
class NewPoster extends Poster[NewStuff] {
def translate(i: Int):NewStuff = new NewStuff(3)
}
class OldPoster extends Poster[OldStuff] {
def translate(i: Int):OldStuff = new OldStuff("A" * 3)
}
val old = new OldPoster()
// so far so good
class Wrapper{
var poster: Poster[_] = null
def setter(p: Poster[_]) = {poster = p }
def prepare_input[A]( ) = {
val i: Int = 5
println(poster.translate(i))
}
}
val w= new Wrapper()
val old = new OldPoster()
w.setter(old)
scala> w.setter(old)
<console>:58: error: type mismatch;
found : OldPoster
required: Poster[_]
w.setter(old)
First, I don't see such error with Scala 2.11.
Then, would be better to avoid erasure by Poster[_]:
class Wrapper[T] {
var poster: Poster[T] = null
def setter(p: Poster[T]) = {poster = p }
def prepare_input() = {
val i: Int = 5
println(poster.translate(i))
}
}
val w= new Wrapper[OldStuff]()
val old = new OldPoster()
w.setter(old)
Finally, not using mutability would make the code more predictable against concurrency.
class Wrapper[T](poster: Poster[T]) {
def prepare_input() = {
val i: Int = 5
println(poster.translate(i))
}
}
val w = new Wrapper(new OldPoster())

Scala Reflection Conundrum: Can you explain these weird results?

I wrote some Scala code, using reflection, that returns all vals in an object that are of a certain type. Below are three versions of this code. One of them works but is ugly. Two attempts to improve it don't work, in very different ways. Can you explain why?
First, the code:
import scala.reflect.runtime._
import scala.util.Try
trait ScopeBase[T] {
// this version tries to generalize the type. The only difference
// from the working version is [T] instead of [String]
def enumerateBase[S: universe.TypeTag]: Seq[T] = {
val mirror = currentMirror.reflect(this)
universe.typeOf[S].decls.map {
decl => Try(mirror.reflectField(decl.asMethod).get.asInstanceOf[T])
}.filter(_.isSuccess).map(_.get).filter(_ != null).toSeq
}
}
trait ScopeString extends ScopeBase[String] {
// This version works but requires passing the val type
// (String, in this example) explicitly. I don't want to
// duplicate the code for different val types.
def enumerate[S: universe.TypeTag]: Seq[String] = {
val mirror = currentMirror.reflect(this)
universe.typeOf[S].decls.map {
decl => Try(mirror.reflectField(decl.asMethod).get.asInstanceOf[String])
}.filter(_.isSuccess).map(_.get).filter(_ != null).toSeq
}
// This version tries to avoid passing the object's type
// as the [S] type parameter. After all, the method is called
// on the object itself; so why pass the type?
def enumerateThis: Seq[String] = {
val mirror = currentMirror.reflect(this)
universe.typeOf[this.type].decls.map {
decl => Try(mirror.reflectField(decl.asMethod).get.asInstanceOf[String])
}.filter(_.isSuccess).map(_.get).filter(_ != null).toSeq
}
}
// The working example
object Test1 extends ScopeString {
val IntField: Int = 13
val StringField: String = "test"
lazy val fields = enumerate[Test1.type]
}
// This shows how the attempt to generalize the type doesn't work
object Test2 extends ScopeString {
val IntField: Int = 13
val StringField: String = "test"
lazy val fields = enumerateBase[Test2.type]
}
// This shows how the attempt to drop the object's type doesn't work
object Test3 extends ScopeString {
val IntField: Int = 13
val StringField: String = "test"
lazy val fields = enumerateThis
}
val test1 = Test1.fields // List(test)
val test2 = Test2.fields // List(13, test)
val test3 = Test3.fields // List()
The "enumerate" method does work. However, as you can see from the Test1 example, it requires passing the object's own type (Test1.type) as a parameter, which should not have been necessary. The "enumerateThis" method tries to avoid that but fails, producing an empty list. The "enumerateBase" method attempts to generalize the "enumerate" code by passing the val type as a parameter. But it fails, too, producing the list of all vals, not just those of a certain type.
Any idea what's going on?
Your problem in your generic implementation is the loss of the type information of T. Also, don't use exceptions as your primary method of control logic (it's very slow!). Here's a working version of your base.
abstract class ScopeBase[T : universe.TypeTag, S <: ScopeBase[T, S] : universe.TypeTag : scala.reflect.ClassTag] {
self: S =>
def enumerateBase: Seq[T] = {
val mirror = currentMirror.reflect(this)
universe.typeOf[S].baseClasses.map(_.asType.toType).flatMap(
_.decls
.filter(_.typeSignature.resultType <:< universe.typeOf[T])
.filter(_.isMethod)
.map(_.asMethod)
.filter(_.isAccessor)
.map(decl => mirror.reflectMethod(decl).apply().asInstanceOf[T])
.filter(_ != null)
).toSeq
}
}
trait Inherit {
val StringField2: String = "test2"
}
class Test1 extends ScopeBase[String, Test1] with Inherit {
val IntField: Int = 13
val StringField: String = "test"
lazy val fields = enumerateBase
}
object Test extends App {
println(new Test1().fields)
}
Instead of getting the type from universe.typeOf you can use the runtime class currentMirror.classSymbol(getClass).toType, below is an example that works:
def enumerateThis: Seq[String] = {
val mirror = currentMirror.reflect(this)
currentMirror.classSymbol(getClass).toType.decls.map {
decl => Try(mirror.reflectField(decl.asMethod).get.asInstanceOf[String])
}.filter(_.isSuccess).map(_.get).filter(_ != null).toSeq
}
//prints List(test)
With everyone's help, here's the final version that works:
import scala.reflect.runtime.{currentMirror, universe}
abstract class ScopeBase[T: universe.TypeTag] {
lazy val enumerate: Seq[T] = {
val mirror = currentMirror.reflect(this)
currentMirror.classSymbol(getClass).baseClasses.map(_.asType.toType).flatMap {
_.decls
.filter(_.typeSignature.resultType <:< universe.typeOf[T])
.filter(_.isMethod)
.map(_.asMethod)
.filterNot(_.isConstructor)
.filter(_.paramLists.size == 0)
.map(decl => mirror.reflectField(decl.asMethod).get.asInstanceOf[T])
.filter(_ != null).toSeq
}
}
}
trait FieldScope extends ScopeBase[Field[_]]
trait DbFieldScope extends ScopeBase[DbField[_, _]] {
// etc....
}
As you see from the last few lines, my use cases are limited to scope objects for specific field types. This is why I want to parameterize the scope container. If I wanted to enumerate the fields of multiple types in a single scope container, then I would have parameterized the enumerate method.

Is there a way to call some code after subclass initialization in Scala?

I need to execute some code after the subclass already did all it's initialization, for example:
abstract class A(a:String) {
var sum = 0
def add(n:Int) = { sum += n; sum }
def verify = if (sum > 10) () else throw new Exception
... initialize subclass ...
verify
}
class B extends A("In A") {
val smth = add(50)
// I want to avoid calling `verify` here
}
val b = new B
println(b.smth) // 50
Is there a way to do it?
You need to either use lazy vals in B, or use the "early initializer" so that the vals in B are initialized before the vals in A. Here'a an excellent description of how these two options work: https://github.com/paulp/scala-faq/wiki/Initialization-Order
So it seems I found the answer. I decided to go with the DelayedInit trait approach - I just execute the delayed code (and count number of times it was executed), then execute the needed code when I think that I've seen enough initializations (one for each class in the extension hierarchy). I wrapped it into a trait:
trait AfterInit extends DelayedInit {
def afterInit
private var initCount = 0
private def getInitNumber(clazz: Class[_]):Int =
if (clazz.getSuperclass == classOf[java.lang.Object]) 0 else getInitNumber(clazz.getSuperclass) + 1
final def delayedInit(x: => Unit) {
x
initCount += 1
if (getInitNumber(this.getClass) + 1 == initCount) afterInit
}
}
Usage:
abstract class A(id:String) extends AfterInit {
var sum = 0
def add(n:Int) = { sum += n; sum }
def afterInit = if (sum > 10) () else throw new Exception
}
class B extends A("B") {
val add1 = add(50)
}
new B // no exception
class C extends A("C") {
val add2 = add(5)
}
new C // exception is thrown, since the `sum` was too small

Scala default parameters and null

I have a method like this:
def aMethod(param: String = "asdf") = {
...
}
If the method is called as follows, then param is given the default value "asdf":
aMethod() ...
But what I would like, is that if the method is called with null, then the default value would also be applied:
aMethod(null) //inside the method, I can use `param` and it has the value "asdf".
Whats the best way to do this in Scala? I can think of pattern matching or a simple if statement.
Pattern matching
def aMethod(param: String = null) {
val paramOrDefault = param match {
case null => "asdf"
case s => s
}
}
Option (implicitly)
def aMethod(param: String = null) {
val paramOrDefault = Option(param).getOrElse("asdf")
}
Option (explicitly)
def aMethod(param: Option[String] = None) {
val paramOrDefault = param getOrElse "asdf"
}
The last approach is actually the most idiomatic and readable once you get use to it.
def aMethod(param: String = null) = {
val p =
if(param == null)
"asdf"
else
param
println(p)
}
But the question must be asked: why allow null? Would Option be possible in your case? For this you could do:
def aMethod(param: Option[String]) = {
val p = param.getOrElse("asdf")
println(p)
}
This makes it clear that your method expects the possibility of a "null" argument.
If the method has just one or two default parameters that can be set to null consider this pattern:
// please note that you must specify function return type
def aMethod (x:String = "asdf"):String = if (x==null) aMethod() else {
// aMethod body ...
x
}
There are some benefits:
The method definition clearly indicates the parameter's default value.
The correct default value can be picked by Scala tools, including ScalaDoc.
There is no need to define an additional value to substitute for the original parameter within the method body - less room for mistakes, easier to reason.
The pattern is fairly concise.
Furthermore, consider the following scenario:
trait ATrait {
def aMethod (x:String = "trait's default value for x"):String
}
class AClass extends ATrait {
....
}
Clearly, here we need to extend the trait, whilst preserving the original default value. Any of the patterns that involve initially setting the parameter to null followed by a check and actual default value will break the contract established by the trait:
class AClass extends ATrait {
// wrong, breaks the expected contract
def aMethod(x: String = null):String = {
val xVal = if (x == null) "asdf" else x
...
}
}
Indeed in this scenario the only way to preserve the original value from ATrait will be:
class AClass extends ATrait {
override def aMethod (x:String):String = if (x==null) aMethod() else {
... // x contains default value defined within ATrait
}
}
However, in the scenario when there are more than one or two default parameters that can be set to null the pattern starts getting rather messy:
// two parameters
def aMethod (x:String = "Hello",y:String = "World"):String =
if (x==null) aMethod(y=y) else
if (y==null) aMethod(x=x) else {
// aMethod body ...
x + " " + y
}
// three parameters
def aMethod (x:String = "Hello",y:String = " ",z:String = "World"):String =
if (x==null) aMethod(y=y,z=z) else
if (y==null) aMethod(x=x,z=z) else
if (z==null) aMethod(x=x,y=y) else {
// aMethod body ...
x + y + z
}
Still when overriding an existing contract this might be the only way to honour the original default values.