Enums for scala

Scala has very limited implementation of Enumeration. Enumerated objects can’t extends other classes. Partial replacement for it is to use sealed classes. You can do pattern matching on them. When you ommit some possible value you will get compiler wa…

Scala has very limited implementation of Enumeration. Enumerated objects can’t extends other classes. Partial replacement for it is to use sealed classes. You can do pattern matching on them. When you ommit some possible value you will get compiler warning for not exhaustive pattern matching. One missing feature is that you can’t get sorted values of all objects extending them. You can simple got it using my (40-lines) EnumOf class from scala-enum. Examples below.

Declaration

sealed abstract class Color(red: Double, green: Double, blue: Double)

object Color extends EnumOf[Color] {
  case object Red   extends Color(1, 0, 0)
  case object Green extends Color(0, 1, 0)
  case object Blue  extends Color(0, 0, 1)
  case object White extends Color(0, 0, 0)
  case object Black extends Color(1, 1, 1)
}

Usage

Color.values shouldEqual List(Red, Green, Blue, White, Black)

Color.valueOfOpt("Blue").value shouldEqual Blue
Color.valueOfOpt("NotExisiting").isEmpty shouldBe true

You can also enumerate on objects nested in instances

Declaration

case class DistanceFrom(srcCity: String, srcCoordinates: Coordinate) extends EnumOf[DistanceBetween] {

    case object ToBerlin extends DistanceFromSrcCityTo("Berlin", Coordinate(52.5075419, 13.4251364))
    case object ToNewYork extends DistanceFromSrcCityTo("New York", Coordinate(40.7033127, -73.979681))
    abstract class DistanceFromSrcCityTo(val destCity: String, val destCoordinates: Coordinate) extends DistanceBetween {
        override def srcCoordinates: Coordinate = DistanceFrom.this.srcCoordinates
    } 
}

sealed abstract class DistanceBetween {
    def srcCoordinates: Coordinate
    def destCity: String
    def destCoordinates: Coordinate
    def inKm: Int = Coordinate.distanceInKm(srcCoordinates, destCoordinates).toInt
}

Usage

val DistanceFromWarsaw = DistanceFrom("Warsaw", Coordinate(52.232938, 21.0611941))
DistanceFromWarsaw.ToBerlin.inKm shouldEqual 519
DistanceFromWarsaw.ToNewYork.inKm shouldEqual 6856
DistanceFromWarsaw.values.map(_.inKm) shouldEqual List(519, 6856)
You May Also Like

Need to make a quick json fixes – JSONPath for rescue

From time to time I have a need to do some fixes in my json data. In a world of flat files I do this with grep/sed/awk tool chain. How to handle it for JSON? Searching for a solution I came across the JSONPath. It quite mature tool (from 2007) but I haven't hear about it so I decided to share my experience with others.

First of all you can try it without pain online: http://jsonpath.curiousconcept.com/. Full syntax is described at http://goessner.net/articles/JsonPath/



But also you can download python binding and run it from command line:
$ sudo apt-get install python-jsonpath-rw
$ sudo apt-get install python-setuptools
$ sudo easy_install -U jsonpath

After that you can use inside python or with simple cli wrapper:
#!/usr/bin/python
import sys, json, jsonpath

path = sys.argv[
1]

result = jsonpath.jsonpath(json.load(sys.stdin), path)
print json.dumps(result, indent=2)

… you can use it in your shell e.g. for json:
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
}
}

You can print only book nodes with price lower than 10 by:
$ jsonpath '$..book[?(@.price 

Result:
[
{
"category": "reference",
"price": 8.95,
"title": "Sayings of the Century",
"author": "Nigel Rees"
},
{
"category": "fiction",
"price": 8.99,
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"author": "Herman Melville"
}
]

Have a nice JSON hacking!From time to time I have a need to do some fixes in my json data. In a world of flat files I do this with grep/sed/awk tool chain. How to handle it for JSON? Searching for a solution I came across the JSONPath. It quite mature tool (from 2007) but I haven't hear about it so I decided to share my experience with others.