1

I have a factory that should return an implementation depending on the name.

    val moduleMap = Map(Modules.moduleName -> new ModuleImpl)
    def getModule(moduleName: String): Module =
        moduleMap.get(moduleName) match {
          case Some(m) => m
          case _ =>
            throw new ModuleNotFoundException(
              s"$moduleName - Module could not be found.")
        }

In order for each call to the "getModule" method not to create an instance, there is a map in which all the modules must be initialized in bootstrap class. I would like to get rid of the need to do this manually(also all classes have a distinctive feature).

List of options that came to my mind:

  • Reflection(we can use Scala Reflection API or any thrid-party library)
    • Automated process.
    • Need to initialize immediately at startup.
    • Reflection is a pain.
  • Metaprogramming(ScalaMeta) + Reflection
    • Macros only change the code, the execution happens later.

Can we move initialization process to compile time?

I know that compiler can optimize and replace code, next fragment before compilation

val a = 5 + 5

after compilation compiler change that piece to 10, can we use some directives or another tools to evaluate and execute some code at compile time and use only final value?

1 Answers1

0

Do you use any framework or you write your own? I answered similar question about Guice here. You can use it without Guice as well: instead of Module you will have your Factory, which you need to initialize from somewhere, and during initialization, you will fill your map using reflection

In general I think it is the easiest approach. Alternatively, you can write macros, which just replaces part of reflective initialization, but not sure that it will give you some profit (if I understand your question right, this initialization will happen just once at startup).

I do not see how scalameta can help you? Probably, only in case if all your implementations are in source tree available to you, so you can analyze it and generate initialization (similar to macros)? Probably, this would add such plus as easier search for implementation, but will add minus: will work only on implementations in your sources.

Your example of compile-time optimization is not applicable. In your example, you talk about compile-time constant (even with arithmetic it could be a problem, see this comment), but in your question you need specific run-time behavior. So compile time could be only code generation from macros or based on scalameta from my point of view.

Evgeny
  • 1,760
  • 10
  • 11
  • I don't use any frameworks, my implementation so simple that i can describe modules initialization manually, but I want to get to know more about other possibilities.) – user2607928 Mar 26 '18 at 19:50
  • scalaMeta, Macros - this is a great opportunity that has a their own problems. You can't debug code that was added using macros, strange syntax, difficult to understand, etc.., but also you just expand or generate new source(Class\Method\Variable) that compile in java byte code -> machine commands. This code will still be computed and when i initialize factory, generated code will be runned, jvm spend time to calcuate value and etc.. I wanted to know if we can run a piece of code at compile time and in runtime use specific value. Anyway, thanks for the link to the resource – user2607928 Mar 26 '18 at 20:04