How to add a method to Enumeration in Scala?
Here is an example of adding attributes to scala enums by extending the Enumeration.Val class.
object Planet extends Enumeration { protected case class Val(val mass: Double, val radius: Double) extends super.Val { def surfaceGravity: Double = Planet.G * mass / (radius * radius) def surfaceWeight(otherMass: Double): Double = otherMass * surfaceGravity } implicit def valueToPlanetVal(x: Value) = x.asInstanceOf[Val] val G: Double = 6.67300E-11 val Mercury = Val(3.303e+23, 2.4397e6) val Venus = Val(4.869e+24, 6.0518e6) val Earth = Val(5.976e+24, 6.37814e6) val Mars = Val(6.421e+23, 3.3972e6) val Jupiter = Val(1.9e+27, 7.1492e7) val Saturn = Val(5.688e+26, 6.0268e7) val Uranus = Val(8.686e+25, 2.5559e7) val Neptune = Val(1.024e+26, 2.4746e7) } scala> Planet.values.filter(_.radius > 7.0e6) res16: Planet.ValueSet = Planet.ValueSet(Jupiter, Saturn, Uranus, Neptune)
Building on Chris' solution, you can achieve somewhat nicer syntax with an implicit conversion:
object Suit extends Enumeration { val Clubs, Diamonds, Hearts, Spades = Value class SuitValue(suit: Value) { def isRed = !isBlack def isBlack = suit match { case Clubs | Spades => true case _ => false } } implicit def value2SuitValue(suit: Value) = new SuitValue(suit)}
Then you can call, for example, Suit.Clubs.isRed
.
Scala enumerations are distinct from Java enumerations.
At the moment, there is no way add methods to it (in a sane way). There are some work-arounds, but nothing which works in all cases and doesn't look like syntactic garbage.
I tried something similiar (adding methods to enumerated instance of a class, while being able to create new instances at runtime and having a working equivalence relationship between the object
s and the new
instances of the class), but was stopped by bug #4023 ("getClasses/getDeclaredClasses seems to miss some (REPL) or all (scalac) classes (objects) declared").
Have a look at these related questions by me:
- Is it possible to “explore” which objects are defined within an other object via reflection at runtime?
- How to access objects within an object by mixing in a trait with reflection?
Honestly, I wouldn't use Enumeration
. This is a class originating from Scala 1.0 (2004) and it has weird stuff in it and not many people (except those who have written it) understands how to use it without an tutorial first.
If I would absolutely need an enumeration I would just write that class in Java.