19 Aug, 2009, David Haley wrote in the 1st comment:
Votes: 0
There is a library for Lua called Pluto that purports to be able to serialize pretty much everything. The interesting thing about Pluto is that it uses C extensions to serialize more than you can with a pure Lua solution (which cannot, for example, serialize functions).

Since interest in serialization appears to be topical, I gave it a whirl to see how easy it would be to use. I was pleasantly surprised at how easy it was to serialize a simple lambda.

The test case is to create a function implementing a counter using closures. In other words, every time you call it, it will return the next number. It keeps track of its state using upvalues: no global variables, and no "functor" object to store state. It's a nice trick that functional language programmers will be quite familiar with.

require 'pluto'

function f(x)
return function()
x = x + 1
return x

g = f(0)

print("calling g, expecting 1")
print("calling g, expecting 2")

print("serializing g, when x is 2")
s = pluto.persist({}, {g = g})

print("calling g, expecting 3")

print("unserializing g (that was saved with x=2) into g2")

objs = pluto.unpersist({}, s)
g2 = objs.g

print("calling g2, expecting 3 *again*")

print("calling g2, expecting 4")

print("calling g, expecting 4")

Now let's run it and see what happens:
$ lua test.lua
calling g, expecting 1
calling g, expecting 2
serializing g, when x is 2
calling g, expecting 3
unserializing g (that was saved with x=2) into g2
calling g2, expecting 3 *again*
calling g2, expecting 4
calling g, expecting 4

We see that the function serialization worked, and isn't doing anything funky with the program state. After deserialization, we have two copies of the function as expected, each with its own closure. That is why calling g2 gives us 3 and then , and calling g (the original function) gives us 4. The two functions are tracking their state separately.

The above is quite obviously a contrived example, but it shows that you can serialize whole functions along with their closures. I also played with writing the function out to disk and loading it up in a wholly separate Lua interpreter instance, which worked as well.

When you serialize objects, you can specify things not to serialize, such as library functions, the globals table, and so forth. This lets you cut down on serialization size (don't bother serializing things that needn't be) but also serialize more accurately: you can serialize an object's state, but not its methods, so that you can restore the state into a copy of the object with updated class code.

Pluto purports to be able to serialize whole coroutines (basically, threads of execution) as well, although I have not tried that yet.

The above was done with Lua 5.1.4 and Pluto 2.4 (the most recent version) using the patch below.


NOTE: if you try to install Pluto on a 64-bit system, you will need to patch it slightly. Please see this post for more information. The patch is the following:
— ../pluto-pristine/pluto.c	2008-04-15 12:58:16.000000000 -0500
+++ pluto.c 2009-08-18 11:51:49.472726525 -0500
@@ -890,10 +890,10 @@
static void unpersiststring(UnpersistInfo *upi)
/* perms reftbl sptbl ref */
- int length;
+ size_t length;
char* string;
lua_checkstack(upi->L, 1);
- verify(LIF(Z,read)(&upi->zio, &length, sizeof(int)) == 0);
+ verify(LIF(Z,read)(&upi->zio, &length, sizeof(size_t)) == 0);
string = pdep_newvector(upi->L, length, char);
verify(LIF(Z,read)(&upi->zio, string, length) == 0);
lua_pushlstring(upi->L, string, length);
03 Nov, 2009, JohnnyStarr wrote in the 2nd comment:
Votes: 0
This is very cool. I've been messing around with Lua the last couple of days because I want to understand it.
So far, I've enjoyed how minimalistic yet powerful it can be. I am playing with the idea of embedding it into my
Rom project. I do wish there was more info in the Lua section though. I hope that there are more folks out there
that have similar goals.
03 Nov, 2009, David Haley wrote in the 3rd comment:
Votes: 0
Lua is a very powerful embedding language, and very easy to hook into a project. I don't think it's ideal for writing an entire application in (at least, not until you have the usual OO scaffolding and standard libraries written) but so far I've found it hard to beat as an embedded language. (Well, it was designed for that, after all…)

I'm using it in a graphical game project for various purposes. For example, I use it as a very easy way to parse tile descriptions. I hope to put up a few posts showing how that works at some point soon (probably this weekend?).