This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Enums, Eager, and a Null object

No replies
JamesJ
Joined: 2010-01-24,
User offline. Last seen 42 years 45 weeks ago.
Hi,
To understand my question, I first have to give a short explanation.
I was unhappy with Scala Enums lack of extensibility, and didn't like the case class solution because it didn't offer iteration.
I ended up creating a "least-pain" (for my programming style), where I added ordering to a set of sealed case classes and built in a bit of "at least catch the dumb stuff" implicit error checking.

This leads me to my second part of the subject, "Eager".  The "object" key word seems to be "lazy" by default, but this is not helpful in my case.  I want the objectness that implies that there is only one, but I also want it all initialized at the same time is other stuff
My Question:  Could we have a converse to lazy keyword, that makes objects init early instead of waiting to be accessed?  It could be called, eager, !lazy or whatever.

Third part:  I would never have guessed that I could get a null when accessing objects, but I ran across it yesterday.  Any insight would be appreciated.If I access order first, all is well, but if I touch a case object first, then that case object is returned as null subsequently.  I am using 2.8
Thanks
JamesJ
------------------------------- Code that breaks stuff
package junk
import com.kybios.scalaUtil.AltEnum
object SampleEnum extends AltEnum{    sealed class SampleId(val someString:String) extends Value
    case object FIRST extends SampleId("Wow")    case object SECOND extends SampleId("No Way")     case object THIRD extends SampleId("Yah")
    val order = defineOrder(FIRST::SECOND::THIRD::Nil)
}
object Main {    def main(args: Array[String]): Unit = {         import SampleEnum._        //val tmp = FIRST  // ****** Uncomment this statement to break stuff **********        println("enum list :" + order)        for( j <- order){             println(" "+j.name+"  id = "+j.id+"  someString = "+j.someString)        }     }}

------------------------------- My alternate enum solution utilized abovepackage com.kybios.scalaUtil
abstract class AltEnum{     private var orderDefined = false    private var privValues:Option[List[Value]] = None    lazy val values:List[Value] = {        if( ! orderDefined ) throw new Error("Tried to access id without defining order")         // this shouldn't be empty if orderDefined        if( privValues.isEmpty ) throw new Error("Unexpected empty priv value")        privValues.get    }    def defineOrder[T <: Value](list:List[T]):List[T]={         orderDefined = true        var nextId = 0        list.foreach( (v)=>{            v.privId = nextId            nextId += 1            v.id // cause id to init         })        privValues = Some(list)        list    }
    // look through list and find value with id    def getById[T<:Value](id:Int, list:List[T]):Option[T]={         list.find((i)=>{i.id == id})    }    // look through list and find value with id    def getByName[T<:Value](name:String, list:List[T]):Option[T]={         list.find((i)=>{i.name == name})    }
    protected class Value(){        if( orderDefined ) throw new Error("Created value or accessed value that was not in defined order")         private[AltEnum] var privId:Int = -1        lazy val id = {            if( ! orderDefined ) throw new Error("Tried to access id without defining order")            privId         }        lazy val name = {            if( ! orderDefined ) throw new Error("Tried to access name without defining order")            this.toString        }     }}

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland