I
I
ivnik2013-05-17 15:43:02
Scala
ivnik, 2013-05-17 15:43:02

Scala (2.10.x) and reflection question - how to distinguish primary constructor arguments from "fields"

There is class B inheriting from class A:

class A(val aparam: String) {...}

class B(bparam: String) extends A(bparam) {
    var someb1 = "somevalue"
    val someb2 = "somevalue"
}

If using reflection to examine class B:

val b = new B("hello")

val mirror = runtimeMirror(b.getClass.getClassLoader)
val alltypes = mirror.reflect(b).symbol.typeSignature.baseClasses.filter(c => c.isClass).map(c => c.asClass.typeSignature)

val vars: Seq[TermSymbol] = alltypes.flatMap(t => t.members.filter(m => m.isTerm && (m.asTerm.isVal || m.asTerm.isVar)).map(x => x.asTerm))

And output "vars", then something like this will be displayed:

value aparam
value bparam
variable someb1
value someb2


Those. the arguments of the primary constructor are also

emitted (bparam)
want to ignore bparam and not ignore aparam (isParamAccessor method
will return true for aparam and bparam)?

If you later try to get the value of bparam through reflection
(for example: vars.map(v => mirror.reflect(b).reflectField(v).get), then an exception will be thrown:

scala.ScalaReflectionException: Scala field aparam isn't represented as a Java
field, neither it has a Java accessor method note that private parameters of
class constructors don't get mapped onto fields and/or accessors, unless they
are used outside of their declaring constructors.

Which they warn about in scaladoc to reflectField:
If a field symbol doesn't correspond to a reflectable entity of the underlying
platform, a ScalaReflectionException exception will be thrown. This might
happen, for example, for primary constructor parameters. Typically they produce
class fields, however, private parameters that aren't used outside the
constructor remain plain parameters of a constructor method of the class.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
O
Ojow, 2013-05-17
@Ojow

So fit?

Welcome to Scala version 2.10.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_41).
Type in expressions to have them evaluated.
Type :help for more information.

scala> class A(val aparam: String)
defined class A

scala> class B(bparam: String) extends A(bparam)
defined class B

scala> import scala.reflect.runtime.{universe => ru}
import scala.reflect.runtime.{universe=>ru}

scala> ru.typeTag[B].tpe.declarations
res3: reflect.runtime.universe.MemberScope = SynchronizedOps(value bparam, constructor B)

Y
Yuri Tatarkin, 2015-03-30
@tomasoyer

This is not an op modx question, but a question about html
On the second question: Site-> Content Types, there you remove the extension from HTML

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question