10

If I have an instance of an object, is there a way to check if I have a singleton object rather than an instance of a class? Is there any method can do this? May be some reflection API? I know that one difference is that the class name of a singleton object ends with a $, but this is not a strict way.

Alberto Bonsanto
  • 17,556
  • 10
  • 64
  • 93
SleePy
  • 127
  • 7

2 Answers2

22

Yep, using the little-documented scala.Singleton type:

def isSingleton[A](a: A)(implicit ev: A <:< Singleton = null) = 
  Option(ev).isDefined

And then:

scala> val X = new Foo(10)
X: Foo = Foo@3d5c818f

scala> object Y extends Foo(11)
defined object Y

scala> isSingleton(X)
res0: Boolean = false

scala> isSingleton(Y)
res1: Boolean = true

My isSingleton method is just a demonstration that provides a runtime boolean value that tells you whether or not an expression is statically typed as a singleton type, but you can also use Singleton as evidence at compile time that a type is a singleton type.

Travis Brown
  • 138,631
  • 12
  • 375
  • 680
  • Why not use `ev ne null` instead of `Option(ev).isDefined`? – Clashsoft Mar 15 '16 at 19:42
  • @Clashsoft No particular reason. The `null` default value is kind of a hack, and since it's not really the point I just wanted to keep things as principled otherwise as possible. – Travis Brown Mar 15 '16 at 19:43
  • Also, are you sure `scala.Singleton` (still) exists? It's not in the `2.11` documentation, and it's not to be found in the GitHub repo either? Maybe you could add a link – Clashsoft Mar 15 '16 at 19:47
  • @Clashsoft It's definitely [still there](https://github.com/scala/scala/search?utf8=%E2%9C%93&q=Singleton), but (as I note) not very documented. – Travis Brown Mar 15 '16 at 19:51
  • It seems to be a [compiler builtin existential type](https://github.com/scala/scala/search?utf8=%E2%9C%93&q=singletonclass&type=Code) (that also gets erased, so no `.isInstanceOf[Singleton]`). – Clashsoft Mar 15 '16 at 19:55
  • Is there any documentation/mention about this at all? – Jasper-M May 23 '16 at 14:29
  • @Jasper-M Well, it's mentioned a couple of times in the language specification, but no, not really. – Travis Brown May 23 '16 at 15:14
0

Here's what I found the best solution to this problem:

import scala.reflect.runtime.currentMirror
def isSingleton(value: Any) = currentMirror.reflect(value).symbol.isModuleClass

Base on How to determine if `this` is an instance of a class or an object?

Community
  • 1
  • 1
Martin Tapp
  • 3,106
  • 3
  • 32
  • 39