#1178 Simple library for freeform objects

ivan Tue 17 Aug 2010

Some time ago I needed ability for convenient work with json objects, so I wrote a small pod and use it about few months. Here's some quick overiview:

//creation
json := Json.makeEmpty
json->strField = "value"
json->intField = 5
json->childObj1 = ["foo":5, "bar":[1,2,3]] //map will be wrapped to Json
json->childObj2 = Json.make(["key": 1]) //Json instance created from map
json->childObj3->foo = 6
json->childList = [Json.makeWith { it->a = "5" }, Json.makeWith { it->b = 6 }]

//const/mutable
constJson := json.toConst
modifiedCopy := constJson.mutate { it->intField = 4 } 
mutable := modifiedCopy.toMutable

//serialization/deserialization
str := json.toStr
constJson := ConstJson.fromStr(str)
mutableJson := Json.fromStream(str.in)

The source is located at Bitbucket, feel free to use/modify/etc :)

Basically there are just two classes in public API - ConstJson and Json which share the same set of methods. Unfortunately it is impossible to create a common mixin for them because const classes can't extend non-const mixins and non-const classes can't extend const mixins. So in the implementation I just have internal class JsonUtil and both classes just delegate its method to this class.

Probably it could be great to have some support for user-defined classes which can be mutable/immutable, so that MyClass.toImmutable will return the instance of const variant of MyClass, or at least the ability to write some mixin (with a limited set of functionality - for example only abstract methods) that can be extended by both const and non-const classes.

qualidafial Tue 17 Aug 2010

Wouldn't it be more Fantomy to make all Json objects const, and use it-blocks for construction and with-blocks for creating altered copies?

json := Json {
  it->strField = "value"
  it->intField = 5
  ...
}

modifiedCopy := json {
  it->intField = 4
}

ivan Tue 17 Aug 2010

probabaly yes, but there's a problem - right now ConstJson::mutate impl looks like this:

ConstJson mutate(|Json| f)
{
  json := toMutable
  f(json)
  return json.toConst
}

So it accepts a closure with one parameter of type Json. In order to satisfy with signature Json class have to extend class ConstJson which is not possible. And anyway we need to have mutable variant of Json which will trap field setting and modify its contents.

Basically I always use only ConstJson and Json class is just helper for implementing mutate method.

Edit: corrected code

Login or Signup to reply.