crockpotveggies
crockpotveggies

Reputation: 13300

How can I serialize anything without specifying type?

I'm integrating with ZeroMQ and Akka to send case classes from different instances. Problem is that when I try to compile this code:

def persistRelay(relayEvent:String, relayData:Any) = {
    val relayData = ser.serialize(relayData).fold(throw _, identity)
    relayPubSocket ! ZMQMessage(Seq(Frame(relayEvent), Frame(relayData)))
  } 

The Scala compilers throws back recursive value relayData needs type.

The case classes going in are all different and look like Team(users:List[Long], teamId:Long) and so on.

Is there a method to allow any type in the serializer or a workaround? I'd prefer to avoid writing a serializer for every single function creating the data unless absolutely necessary.

Thanks!

Upvotes: 0

Views: 160

Answers (1)

Destin
Destin

Reputation: 1214

This isn't really a typing issue. The problem is:

val relayData = ser.serialize(relayData).fold(throw _, identity)

You're declaring a val relayData in the same line that you're making a reference to the method parameter relayData. The Scala compiler doesn't understand that you have/want two variables with the same name, and, instead, interprets it as a recursive definition of val relayData. Changing the name of one of those variables should fix the error.

Regardless, since you didn't quite follow what the Scala compiler was asking for, I think that it would also be good to fill you in on what it is that the compiler even wanted from you (even though it's advice that, if followed, probably would have just led to you getting yet another error that wouldn't seem to make a lot of sense, given the circumstances).

It said "recursive value relayData needs type". The meaning of this is that it wanted you to simply specify the type of relayData by having

val relayData = ...

become something like

val relayData: Serializable = ...

(or, in place of Serializable, use whatever type it was that you wanted relayData to have)

It needs this information in order to create a recursive definition. For instance, take the simple case of

val x = x + 1

This code is... bizarre, to say the least, but what I'm doing is defining x in a (shallowly) recursive way. But there's a problem: how can the compiler know what type to use for the inner x? It can't really determine the type through type inference, because type inference involves leveraging the type information of other definitions, and this definition requires x's type information. Now, we might be able to infer that I'm probably talking about an Int, but, theoretically, x could be so many things! In fact, here's the ambiguity in action:

val x: Int = x + 1 // Default value for an Int is '0'
x: Int = 1

val y: String = y + 1 // Default value for a String is 'null'
y: String = null1

All that really changed was the type annotation, but the results are drastically different–and this is only a very simple case! So, yeah, to summarize all this... in most cases, when it's complaining about recursive values needing types, you should just have some empathy on the poor compiler and give it the type information that it so direly craves. It would do the same for you, DeLongey! It would do the same for you!

Upvotes: 3

Related Questions