Using reflection Scala 2.10, how can I list the values ​​of Enumeration?

Having the following listing

object ResponseType extends Enumeration { val Listing, Album = Value } 

How to get a list of its shafts?

+8
reflection scala enumeration
source share
3 answers

If you want to be thorough in this matter, you need to check that your characters have Value as a supertype:

 def valueSymbols[E <: Enumeration: TypeTag] = { val valueType = typeOf[E#Value] typeOf[E].members.filter(sym => !sym.isMethod && sym.typeSignature.baseType(valueType.typeSymbol) =:= valueType ) } 

Now, even if you have the following (which is completely legal):

 object ResponseType extends Enumeration { val Listing, Album = Value val someNonValueThing = "You don't want this in your list of value symbols!" } 

You will still get the correct answer:

 scala> valueSymbols[ResponseType.type] foreach println value Album value Listing 

Your current approach will include value someNonValueThing here.

+16
source share

The following code gets a list of Symbol objects representing "vals":

 import reflect.runtime.universe._ // Access the reflection api typeOf[ResponseType.Value] // - A `Type`, the basic unit of reflection api .asInstanceOf[TypeRef] // - A specific kind of Type with knowledge of // the place it being referred from .pre // - AFAIK the referring Type .members // - A list of `Symbol` objects representing // all members of this type, including // private and inherited ones, classes and // objects - everything. // `Symbol`s are the second basic unit of // reflection api. .view // - For lazy filtering .filter(_.isTerm) // - Leave only the symbols which extend the // `TermSymbol` type. This is a very broad // category of symbols, which besides values // includes methods, classes and even // packages. .filterNot(_.isMethod) // - filter out the rest .filterNot(_.isModule) .filterNot(_.isClass) .toList // - force the view into a final List 

It should be noted that instead of filtering on is-clauses, it can be implemented with the .collect test for certain types, for example:

 .collect{ case symbol : MethodSymbol => symbol } 

This approach may be required for other tasks in reflection api.

It should also be noted that the use of .view not mandatory at all, it just uses a series of filter applications (as much as other functions, such as map , flatMap , etc. ..) are much more efficient by going through the input collection only once and at the moment when it is actually inserted into a particular collection ( .toList in our case).

Update

As Travis Brown suggested, you can also refer directly to the ResponseType object. Thus, part of typeOf[ResponseType.Value].asInstanceOf[TypeRef].pre can be replaced by typeOf[ResponseType.type]

+6
source share

You can iterate over enumeration values ​​through the set returned by the enumeration value method:

 scala> for (e <- ResponseType.values) println(e) Listing Album 
+3
source share

All Articles