Here is a little pattern I came across. It basically shows how companion objects work like class objects in Ruby and how type inference makes working with such types quite painless. I’m not sure if this is already widely known but a quick search on Google doesn’t reveal anything similar.
Types are not really first-class objects in Scala (and in Java,
too). In generics, they are removed at compile time through type
erasure, and you cannot simply pass a class to a method by saying
method(ClassName)
.
Most of the time, this is not an issue, but sometimes it would be very handy to pass a class to a method, for example when you need to create new objects of a given type. One example I came across was when working on the new Cassandra-based backend for twimpact. By default, Cassandra only supports storing byte arrays, and we needed some infrastructure to serialize objects into byte arrays and back (without using standard Java serialization). Now serializing an object is simple enough: you just write a trait which provides a function for serializing. However, deserializing is a bit harder because you don’t have an object available. So the question is, how does the program know how to deserialize?
In Ruby, you would probably just pass the class object and work with the class methods like this:
The storing part could be done in the same way in Scala (of course with explicitly introducing a trait for the conversion part.)
To retrieve an object, you could pass a converter function like this:
You can actually drop the type parameter on the call to get
Still, this is not as elegant as the Ruby version because the class and the converter are separate entities.
The solution is to use another trait for the conversion back and let the companion object implement that trait:
On closer inspection, the construction is very similar to the class objects in Ruby. The only difference is that you have to explicitly define a trait for the methods you expect, which isn’t so surprising after all. The rest is taken care of by type inference.
Posted by Mikio L. Braun at 2010-06-15 00:00:00 +0000
blog comments powered by Disqus