Jay Taylor's notes

back to listing index

reflection - Getting object instance by string name in scala - Stack Overflow

[web search]
Original source (stackoverflow.com)
Tags: stackoverflow.com
Clipped on: 2012-08-09

I need the object (or "singleton object" or "companion object"... anything but the class) defined by a string name. In other words, if I have:

package myPackage
object myObject

...then is there anything like this:

GetSingletonObjectByName("myPackage.myObject") match {
 
case instance: myPackage.myObject => "instance is what I wanted"
}
Image (Asset 1/5) alt=1,75241127
asked Dec 16 '09 at 8:12
Image (Asset 2/5) alt=6151125

67% accept rate
add comment

3 Answers

up vote 6 down vote accepted

Scala is still missing a reflection API. You can get the an instance of the companion object by loading the companion object class:

import scala.reflect._
def companion[T](implicit man: Manifest[T]) : T =
  man
.erasure.getField("MODULE$").get(man.erasure).asInstanceOf[T]


scala
> companion[List$].make(3, "s")
res0
: List[Any] = List(s, s, s)

To get the untyped companion object you can use the class directly:

import scala.reflect.Manifest
def companionObj[T](implicit man: Manifest[T]) = {
 
val c = Class.forName(man.erasure.getName + "$")
  c
.getField("MODULE$").get(c)
}


scala
> companionObj[List[Int]].asInstanceOf[List$].make(3, "s")
res0
: List[Any] = List(s, s, s)

This depends on the way scala is mapped to java classes.

answered Dec 16 '09 at 8:18
Image (Asset 3/5) alt=12.4k2451
1 upvote
 flag
Holy cow. Do you know if this syntax is a fixed part of the Scala spec (as fixed as anything else in the language, anyway)? It seems like a bad idea to rely on this. And since my goal was to make the code clearer... Thank you! – Dave Dec 17 '09 at 11:24
  upvote
 flag
As he mentioned, there is no reflection API in Scala yet, so whether this is covered by the Scala spec or not, this is the only way for you to do it. I noticed this question / answer is over a year old, are there any news here? – pdinklag Feb 17 '11 at 5:37
add comment

Barring reflection tricks, you can't. Note, for instance, how the method companion is defined on Scala 2.8 collections -- it is there so an instance of a class can get the companion object, which is otherwise not possible.

answered Dec 16 '09 at 10:49
Image (Asset 4/5) alt=95.6k12169346
  upvote
 flag
Could you add a link to the source, please? – Thomas Jung Dec 16 '09 at 12:11
  upvote
 flag
lampsvn.epfl.ch/trac/scala/browser/scala/trunk/src/library/…, though, hopefully, 2.8's Scaladoc 2 will soon contain links to the source, as already happens with 2.7. – Daniel C. Sobral Dec 17 '09 at 11:24
add comment

Adjustment to Thomas Jung's answer above: you would do better to say companion[List.type] because a) this should be a stable way to refer to it, not dependant on the name mangling scheme and b) you get the unerased types.

def singleton[T](implicit man: reflect.Manifest[T]) = {
 
val name = man.erasure.getName()
  assert
(name endsWith "$", "Not an object: " + name)
 
val clazz = java.lang.Class.forName(name)

  clazz
.getField("MODULE$").get(clazz).asInstanceOf[T]
}  

scala
> singleton[List.type].make(3, "a")                      
res0
: List[java.lang.String] = List(a, a, a)
answered Jan 11 '10 at 19:50
Image (Asset 5/5) alt=5,706522
  upvote
 flag
Very nice! Still a little wonky for my tastes but I may use this... – Dave Jan 12 '10 at 1:18
  upvote
 flag
How is this better than just List.make(3, "a")? The OP wanted to get the object by string name – IttayD Nov 7 '10 at 12:51
  upvote
 flag
Thanks! This is exactly what I was looking for. It's certainly a hack, but less dirty than what I managed to come up with. – Tomer Gabel Jun 27 '11 at 14:19
add comment

Your Answer

 
community wiki

Not the answer you're looking for? Browse other questions tagged or ask your own question.