Tuesday, August 14, 2012

Scala-IO Core: Output - OutputConverter

As mentioned in the last post on Output, it is possible to write arbitrary objects to an output object and have it serialized to disk.

The way this is handled in Scala-IO is via OutputConverters.  If you are familiar with the type-class pattern then this should be very clear to you how this works.  For a very quick introduction you can read: http://www.sidewayscoding.com/2011/01/introduction-to-type-classes-in-scala.html.

The clue is in the signature of write:
1
def write[T](data: T)(implicit writer: OutputConverter[T]): Unit

the last parameter is the object that defines how the object is serialized.  The OutputConverter trait essentially converts and object into bytes and has a few built-in implementations in its companion object for objects like Int, Float, Byte, Char, etc... 

Since the parameter is implicit the compiler will search for an implementation that satisfies the requirements (that the OutputConverter has the type parameter T).  This allows:
1
2
3
4
5
6
7
8
9
10
11
12
import scalax.io._
 
val output:Output = Resource.fromFile("scala-io.out")
 
output write 3
 
// and
 
output write Seq(1,2,3)
 
// one can be more explicit and declare the OutputConverter
output.write(3)(OutputConverter.IntConverter)
The last line in the example shows the explicit declaration of the OutputConverter to use when writing the data. This indicates how one can provide their own converter.

Since the parameter is implicit there are two ways that custom OutputConverters can be used.
  • defining an implicit object for the object to be written. In this case all the possible ways implicits can be defined can be used. For example as an implicit value or in the companion object of the object to be written (serialized)
  • Explicitly declare the converter to use at the method call site

First let's examine the use-case where the object is from a different library and therefore we cannot create a companion object for the object.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.util.Date
import scalax.io._
import Resource._
import OutputConverter._
val file = fromFile("scala-io.out")
 
// Simplest design pattern is to create a new implicit object in scope
implicit object DateConverter extends OutputConverter[Date] {
  def sizeInBytes = 8
  def toBytes(data: Date) = LongConverter.toBytes(data.getTime)
}
 
file.write(java.util.Calendar.getInstance().getTime())
 
// display result in REPL
file.byteArray
 
// naturally the write method can have the converter
// explicitly declared if you don't want to make the
// object implicit
file.write(java.util.Calendar.getInstance().getTime())(DateConverter)
The second case is where you are implementing the class and therefore can add a companion object:
For this next bit to work you need to paste it into a file and run that or use the paste mechanism of the REPL (type :paste into repl and press enter)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import scalax.io._
import Resource._
import OutputConverter._
 
class MyData(val name:String)
object MyData {
  implicit object Converter extends OutputConverter[MyData] {
    def sizeInBytes = 1
    def toBytes(data: MyData) = data.name.getBytes("UTF8")
  }
}
val file = fromFile("scala-io.out")
 
// lets quickly delete file to make sure we are dealing with
// and empty file (this is a method on Seekable)
file.truncate(0)
 
file write (new MyData("jesse"))
 
// display result in REPL
file.string

6 comments:

  1. "def sizeInBytes = 1", is that correct?

    ReplyDelete
    Replies
    1. Size in bytes is a part of the API that is not yet solid. I am still playing with that. I think 1 is wrong but it doesn't matter in this case

      Delete
  2. You said "case-class" when you meant "type-class".

    ReplyDelete
  3. Good blog details with output converters, for more information and training free tutorials, free demo can visit.....


    Check this site Tekslate for in scala Training
    Go here if you’re looking for information scala Training

    ReplyDelete
  4. Good blog details with output converters, for more information and training free tutorials, free demo can visit.....


    Check this site Tekslate for in scala Training
    Go here if you’re looking for information scala Training

    ReplyDelete