This is a suggested addition to the serialize.lua file, described and implmented here: http://www.gammon.com.au/forum/bbshowpost.php?id=4960
Fadedparadox and I were chatting a bit, and he had shown me his serialization functions to pack a Lua table into a MUSHclient variable. I noticed that it didn't handle functions, and he explained why. It stuck in my head though, I guess.
Today we were talking, and it came up again. I experimented a bit, dumping a basic function and iterating over each of its bytes (printing out the char number for each). The functions all have a lot of null bytes, so I figured that, since MUSHclient is written in C++, and cstrings are null-terminated, that's probably why storing/getting a dumped function doesn't work: it only stores "LuaQ".
A half-hour's pondering came up with a handy solution: encode the functions in base64 before storing them. I initially tried Base64Encode(), which didn't work because it was a C function exposed to Lua, so I wasted a few hours trying to write my own encoder/decoder. Then Fadedparadox pointed out utils.base64encode, heh.
In short: Given a function, get its string.dump representation, and use utils.base64encode on it to make it MUSH-variable friendly. To retrieve, use utils.base64decode and loadstring(). Example:
If this technique is used to store a function that's part of a table, you can build in the loadstring yourself, though obviously the user still has to loadstring the overall table:
Fadedparadox and I were chatting a bit, and he had shown me his serialization functions to pack a Lua table into a MUSHclient variable. I noticed that it didn't handle functions, and he explained why. It stuck in my head though, I guess.
Today we were talking, and it came up again. I experimented a bit, dumping a basic function and iterating over each of its bytes (printing out the char number for each). The functions all have a lot of null bytes, so I figured that, since MUSHclient is written in C++, and cstrings are null-terminated, that's probably why storing/getting a dumped function doesn't work: it only stores "LuaQ".
A half-hour's pondering came up with a handy solution: encode the functions in base64 before storing them. I initially tried Base64Encode(), which didn't work because it was a C function exposed to Lua, so I wasted a few hours trying to write my own encoder/decoder. Then Fadedparadox pointed out utils.base64encode, heh.
In short: Given a function, get its string.dump representation, and use utils.base64encode on it to make it MUSH-variable friendly. To retrieve, use utils.base64decode and loadstring(). Example:
function foo()
return 42
end
encoded = utils.base64encode(string.dump(foo))
SetVariable("function_foo", encoded)
retrieved = GetVariable("function_foo")
newfoo = loadstring(utils.base64decode(retrieved))
Note(newfoo()) -- displays '42'
If this technique is used to store a function that's part of a table, you can build in the loadstring yourself, though obviously the user still has to loadstring the overall table:
out = [[ sometable = {
foo = loadstring(base64decode("]] .. utils.base64encode(string.dump(foo)) .. [["))
}]]
loadstring(out)()
Note(sometable.foo())