0

In C++ one can implement a dispatcher-callback pattern with statically registered callbacks, thanks to the static members. In Scala, however, all objects are lazily initialized, so the code below doesn't really work as similar things in C++.

object Main {
    var callbacks = List[()=>Unit]()
    def main(args: Array[String]): Unit = {
        println("hello")
        callbacks.foreach { _() }
    }
}
object A {
    val callbackA = () => println("A")
    Main.callbacks = callbackA::Main.callbacks
}
object B {
    val callbackB = () => println("B")
    Main.callbacks = callbackB::Main.callbacks
}
object C {
    val callbackC = () => println("C")
    Main.callbacks = callbackC::Main.callbacks
}

When I run this program, none of the callbacks are invoked, because objects A, B, and C are never initialized and the registrations are never executed. Is there is a way in Scala to correctly implement what I intend here?

uraj
  • 339
  • 1
  • 10
  • 1
    The code in `A`, `B` and `C` is actually never run. So your `main` method just iterates over an empty collection with `foreach`. I am not sure what your intentions are. – PermaFrost Nov 17 '16 at 21:41
  • @PermaFrost Suppose similar things are written in C++ and Java they would work. I want to know if it's possible to do the same in Scala. To be specific, I want to register the callbacks without the dispatcher knowing their existence. Like how LLVM passes are registered. – uraj Nov 17 '16 at 21:45
  • Maybe you should show how you would write this in Java. Java's static members are also lazily initialized. – Jasper-M Nov 17 '16 at 21:56
  • @Jasper-M Maybe. I never tried that in Java. But C++ definitely works, so I was hoping to get some solutions. – uraj Nov 17 '16 at 22:00
  • I'd go with the suggested answer, I don't see any other option. – PermaFrost Nov 17 '16 at 22:02

1 Answers1

3

You can use reflection to make a list of "all classes that implement trait MyCallback" and add them to a list, at program startup. You would have to define a trait, e.g.

sealed trait MyCallback {
    def callback: Unit
}

In the context of your example, objects A, B and C would extend MyCallback.

For the reflection code, see for instance Finding objects using scala's runtime reflection

Community
  • 1
  • 1
radumanolescu
  • 4,059
  • 2
  • 31
  • 44