开发者

How to access objects within an object by mixing in a trait with reflection?

How can I get all of the objects within an object with reflection?

Consider this code:

object MonthDay extends MyEnum {
  //Some important holidays
  object NewYear       extends MonthDay( 1,  1)
  object UnityDay      extends MonthDay(11,  9)
  object SaintNicholas extends MonthDay(12,  6)
  object Christmas     extends MonthDay(12, 24)
}

class MonthDay(month: Int, day: Int)

trait MyEnum {
  val values: List[MonthDay] = this.getClass.getField("MODULE$")...
  val next: MonthDay = ...
  val previous: MonthDay = ...
}

//Of course the user can create his own MonthDays
val myBirthDay = new MonthDay(month, day)

if(!MonthDay.values.contains(myBirthDay)) "Well, I probably have to work"
else "Great, it is a holiday!"

I want to have a trait (MyEnum) which I can mix into the object holding my "enumeration objects" with methods to return a list of them (def values: List[MonthDay]) or iterate over them (def next: MonthDay or def previous: MonthDay) without repeating myself a few times (this is absolutel开发者_运维技巧y crucial!).

The idea is that values accesses the MonthDay object and finds all singleton objects of the class they are extending (MonthDay) with reflection.


My solution, based on Landei's answer would be:

trait MyEnum{
   def valsOfType[T:Manifest] = {
      val c=implicitly[Manifest[T]].erasure
      for {m <- getClass.getMethods 
           if m.getParameterTypes.isEmpty && c.isAssignableFrom(m.getReturnType)
      } yield (m.invoke(this).asInstanceOf[T])
   }
}

class MonthDay(month:Int,day:Int)

object MonthDay extends MyEnum {
   //maybe you want to call this "holidays" instead
   lazy val values = valsOfType[MonthDay] 

   val NewYear       = new MonthDay( 1,  1)
   val UnityDay      = new MonthDay(11,  9)
   val SaintNicholas = new MonthDay(12,  6)
   val Christmas     = new MonthDay(12, 24)
}

I don't think you should call this MyEnum anymore, because an enumerated type implies a closed set of values.

(Doesn't work if the enumeration values are defined as objects)


Something similar is done in Enumeration.populateNameMap: https://lampsvn.epfl.ch/trac/scala/browser/scala/tags/R_2_8_1_final/src/library/scala/Enumeration.scala


You should be able to use the pre-existing Scala Enumeration class: http://www.scala-lang.org/api/current/scala/Enumeration.html

It seems to come very close to your use-case!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜