Scala: using reflection to discover your inner objects (and desires)?

Is there a way at runtime to detect objects declared inside an external object? Java methods Class getClassesand getDeclaredClassesreturn empty arrays.

object Parent {
    object Child1
    object Child2
}

println("Children of Parent:")
println("   getClasses found %d".format(Parent.getClass.getClasses.size))
println("   getDeclaredClasses found %d".format(Parent.getClass.getDeclaredClasses.size))

Conclusion:

Children of Parent:
  getClasses found 0
  getDeclaredClasses found 0

EDIT: I researched that children register with a parent:

object Parent {
    val children = new collection.mutable.ListBuffer[AnyRef]
    object Child1 { Parent.children += this }
    object Child2 { Parent.children += this }
}

println("(1) Parent.children size: %d".format(Parent.children.size))
Parent.Child1
Parent.Child2
println("(2) Parent.children size: %d".format(Parent.children.size))

(Although this looks ugly, it's actually normal, because I can hide this data with a subclass of creativity and implicit parameters.)

The problem with this approach is that static initializers are not called until references to each type (hence, calls to Parent.Child1and Parent.Child2) that defeat the target are specified . Output:

(1) Parent.children size: 0
(2) Parent.children size: 2

EDIT 2: , ! scalap Parent:

object Parent extends java.lang.Object with scala.ScalaObject {
  def this() = { /* compiled code */ }
  object Child1 extends java.lang.Object with scala.ScalaObject {
    def this() = { /* compiled code */ }
  }
  object Child2 extends java.lang.Object with scala.ScalaObject {
    def this() = { /* compiled code */ }
  }
}
+5
2

, :

object Parent {
  object Child1 
  object Child2 
  val children = List( Child1, Child2 )
}

scala> Parent.children
res: List[ScalaObject] = List(Parent$Child1$@7493931b, Parent$Child2$@49f0d68)

SECOND TRY:

, . :

trait HasChildren {
  val children: AnyRef
}

object Parent extends HasChildren {
  val children = new {
    object Child1
    object Child2
  }
}

scala> Parent.children.getClass.getDeclaredFields
res: Array[java.lang.reflect.Field] = 
  Array(private volatile Parent$$anon$1$Child1$ Parent$$anon$1.Child1$module,
  private volatile Parent$$anon$1$Child2$ Parent$$anon$1.Child2$module)
+1

(Riak standalone) Lift ( MetaRecord.scala) ( ):

  private def isField(m: Method) = classOf[RiakFieldWrapper[A, AnyRef]].isAssignableFrom(m.getReturnType)

  case class FieldHolder(name: String, method: Method, field: RiakFieldWrapper[A, AnyRef])

  def introspect(rec: BucketWrapper[A], methods: Array[Method]): Unit = {
    for (v <- methods if isField(v)) {
      v.invoke(rec) match {
    case rfw: RiakFieldWrapper[A, AnyRef] => tArray += FieldHolder(rfw.keyName, v, rfw)
    case _ =>
      }
    }
  }
+1

All Articles