Lucas
Lucas

Reputation: 347

Scala - Enumeration with value parametrized

I'm wondering if its possible to have Enumerations with one value parametrized.

Something like:

object Animal extends Enumeration {
  val Dog = Value("dog")
  val Cat = Value("cat")
  val Other = Value(?)

  def create(value: String): Animal.Value = {
    Animal.values.find(_.toString == value).getOrElse(Other(value))
  }
}

And, for use, something like:

create("dog") // will return Animal.Dog
create("giraffe") // will return Animal.Other
create("dog").toString // will return "dog"
create("giraffe").toString // will return "giraffe"

That is, to be able to have some values typed, but to leave one free.

Thanks!!! Lucas.

Upvotes: 1

Views: 236

Answers (1)

Silvio Mayolo
Silvio Mayolo

Reputation: 70257

I have to apologize for jumping the gun. I was thinking in Java terms, where an enum is a very rigid thing. Scala, however, is a bit more flexible in that regard. Enumeration does not stop us from extending the enumeration class ourselves.

Disclaimer: This is probably not a good idea. It works, but I don't know how it will behave with respect to serialization or the other nice properties that ordinary enumerations have. So if it works for you, great! But I can't promise that it's a good solution.

object Animal extends Enumeration {
  val Dog = Value("dog")
  val Cat = Value("cat")

  def create(value: String): Animal.Value = {
    Animal.values.find(_.toString == value).getOrElse(OtherAnimal(value))
  }
}

// Extending the enumeration class by hand and giving it a `String` argument.
case class OtherAnimal(name: String) extends Animal.Value {
  override def id = -1
  override def toString = name
}

println(Animal.create("dog").toString)     // dog
println(Animal.create("cat").toString)     // cat
println(Animal.create("giraffe").toString) // giraffe

Upvotes: 3

Related Questions