1

I have a use case where I need to create a class based on user input.

For example, the user input could be : "(Int,fieldname1) : (String,fieldname2) : .. etc" Then a class has to be created as follows at runtime

Class Some
{
   Int fieldname1
   String fieldname2
   ..so..on..
}

Is this something that Scala supports? Any help is really appreciated.

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
Rahul
  • 903
  • 8
  • 16

3 Answers3

4

Your scenario doesn't seem to make sense. It's not so much an issue of runtime instantiation (the JVM can certainly do this with reflection). Really, what you're asking is to dynamically generate a class, which is only useful if your code makes use of it later on. But how can your code make use of it later on if you don't know what it looks like? For example, how would your later code know which fields it could reference?

dhg
  • 52,383
  • 8
  • 123
  • 144
0

No, not really.

The idea of a class is to define a type that can be checked at compile time. You see, creating it at runtime would somewhat contradict that.

You might want to store the user input in a different way, e.g. a map.

What are you trying to achieve by creating a class at runtime?

lutzh
  • 4,917
  • 1
  • 18
  • 21
  • 1
    Well... on the one hand, scala's type system is particularly compile-time-focused (and throws away a lot of type information at runtime), on the other hand, i'm pretty sure you could generate java bytecode and feed it into a classloader to define a new class at runtime. Using it, however, would be equally tedious and involve reflection. – Rob Starling Dec 13 '13 at 17:54
  • I am trying to export the database results with Slick. Slick needs a schema to get the typed information. In my case the results that get returned are dynamic. So, I have to somehow create a class at runtime – Rahul Dec 13 '13 at 18:22
  • You could use Slick's Plain SQL Queries to get generic results (PositionedResult) and map them yourself to your liking. See http://stackoverflow.com/questions/19894465/scala-slick-plain-sql-retrieve-multiple-results-into-list-of-maps – lutzh Dec 17 '13 at 16:51
0

I think this makes sense, as long as you are using your "data model" in a generic manner.

Will this approach work here? Depends.

If your data coming from a file that is read at runtime but available at compile time, then you're in luck and type-safety will be maintained. In fact, you will have two options.

  1. Split your project into two:

    • In the first run, read the file and write the new source programmatically (as Strings, or better, with Treehugger).

    • In the second run, compile your generated class with the rest of your project and use it normally.

  2. If #1 is too "manual", then use Macro Annotations. The idea here is that the main sub-project's compile time follows the macro sub-project's runtime. Therefore, if we provide the main sub-project with an "empty" class, members can be added to it dynamically at compile time using data that the macro sees at runtime. - To get started, Modify the macro to read from a file in this example

Else, if you're data are truly only knowable at runtime, then @Rob Starling's suggestion may work for you as it did me. I'll share my attempt if you want to be a guinea pig. For debugging, I've got an App.scala in there that shows how to pass strings to a runtime class generator and access it at runtime with Java reflection, even define a Scala type alias with it. So the question is, will your new dynamic class serve as a type-parameter in Slick, or fail to, as it sometimes does with other libraries?

Julian Peeters
  • 853
  • 1
  • 6
  • 19
  • Thanks Julian, I think case-class-generator is what I need. I will try this out and let you know. Case class is what Slick uses to query the data. So, if your package is providing the Case Classes with run-time types, my problem will be solved. – Rahul Dec 17 '13 at 18:55
  • Getting the class at runtime is the easy part, making sure it's seen as the proper type is the tricky part. So using the class via reflection will work, but doesn't Slick use them as type-parameters? Some libraries *can* use the generated classes as a type parameter, others choke on it in one way or another. – Julian Peeters Dec 18 '13 at 03:15