3

Namely I would like to write my own valueOf for enums, since this method is removed now by Scala designers (odd call -- https://issues.scala-lang.org/browse/SI-4571).

def valueOf[E <: Enumeration](s : String) =
           E#Value.values.filter(it => it.toString==s).single()

Don't pay much attention to single, it is just Linq-like wrapper (see: Chart of IEnumerable LINQ equivalents in Scala?).

The problem is with E#Value.

Question

How do I access this alias correctly, i.e how do I access type alias of generic type? Please treat this Enum as example!

There is withName method, even if it is considered replacement it is broken by design, value is not a name, so I won't use it to avoid further confusion what the code is doing.

Community
  • 1
  • 1
greenoldman
  • 16,895
  • 26
  • 119
  • 185

1 Answers1

5

The problem with the example is that Enumerations are declared as objects. The object instance can't be looked up based on the class name so a minor change fixes this. Also, do to generics the find method has already digressed to the abstract Value type declared in Enumeration so we need to add an instanceOf to fix the typing. As for the generic alias, E#Value is correct. This provides good typing.

def valueOf[E <: Enumeration](enum: E, s : String): E#Value = 
  enum.values.find( { it => it.toString == s } ).get.asInstanceOf[E#Value]

object WeekDay extends Enumeration {
  val  Sun, Mon, Tue, Wed, Thu, Fri, Sat = Value
}
object Currency extends Enumeration {
  val USD, GBP, EUR = Value
}

val mySun: WeekDay.Value = valueOf(WeekDay,"Sun")
val myCur: Currency.Value = valueOf(WeekDay,"Sun") // fails to compile
Neil Essy
  • 3,607
  • 1
  • 19
  • 23
  • 2
    Thank you very much. Slowly it sinks in "The object instance can't be looked up based on the class name" :-) Does it (IOW) mean it was illegal to call any method for E#Value because it is class, and I needed object to get what I actually defined as my anum (e.g. WeekDay)? – greenoldman Nov 23 '11 at 07:01