Class Models for Lua

# Value Serializer

## `loop.serial.Serializer`

Class of objects that serialize values by creating a chunk of Lua code that when executed creates an isomorphic image of the serialized value, i.e. an identical copy of the original value, that may include self-referecing tables and functions. However there are some limitations, specifically related to function upvalues. It is also possible to define custom serialization for `userdata`. This class is useful to implement persistence mechanisms or remote communication infrastructure.

Each serialized value is processed once for each instance. Serialized objects are stored in the object instance by mapping its value to the serialized string that re-creates the value. However, to properly restore the value the serialized code must be executed by a special method provided by this class (i.e. `load`). The object instance may also store configuration values that define if meta-tables or function environments are serialized along with the values or not.

## Behavior

### Initialization

`Serializer([object])`
  Makes `object` an instance of `Serializer`. Creates an environment that will be used to load serialized values if none is provided. It also register all loaded packages in order to avoid that such packages are serialized.

### Fields

`environment`
  Table used as environment of the serialized code when it is loaded by method `load`. This field must be defined at instantiation otherwise a new table is created and used the environment of loading code. The instance is stored in the environment with the name defined by field `namespace` in order to be accessed by the loading code.
`function`
  Method that serialize function values. If this field evaluates to `false` then function serialization is not allowed and results in Lua errors. By default, this field is a method that serialize the function bytecodes and its environment and upvalues accoding to the settings defined in the instance (see fields `getfenv` and `getupvalue`).
`getfenv`
  Function used to retrieve the environment of a given function. If this field evaluates to `false` then no function environments are serialized. By default this field is the `getfenv` of the Lua library.
`getmetatable`
  Function used to retrieve the metatable of a given table. If this field evaluates to `false` then no metatables are serialized. By default this field is the `getmetatable` of the Lua library.
`getupvalue`
  Function used to retrieve the contents of upvalues of a given function. If this field evaluates to `false` then the contents of function upvalues are not serialized. If the package `debug` is loaded when this class is first required, then the value of this field is the `debug.getupvalue` of the Lua library by default.
`globals`
  Table used as global environment of functions. Functions that have this table as global environment are serialized without such environment and when these functions are restored this table is set as the new environment. By default this field is `_G`.
`namespace`
  String defining the name used in the serialized code to reference the `Serializer` instance. Since the serialized code may be concatenated with other code, this field is used to avoid name collisions. However, this field must be defined at instantiation and should not be changed further.
`package`
  Table that maps the name of packages to the tables representing them. These packages are not serialized, instead a call to the `require` function with the name of the package is used as serialized code for the package. This field is only used when the instance is created thus further changes over this field have no effect. If this value evaluates to `false` then all packages are serialized as ordinary values. By default this field is the field `package.loaded` of the Lua library.
`setfenv`
  Function used to define the environment of a given function. If this field evaluates to `false` then no environments are defined for restored functions. By default this field is the `setfenv` of the Lua library.
`setmetatable`
  Function used to define the metatable of a given table. If this field evaluates to `false` then no metatables are defined for restored tables. By default this field is the `setmetatable` of the Lua library.
`setupvalue`
  Function used to define the contents of upvalues of a given function. If this field evaluates to `false` then the contents of function upvalues are not restored. If the package `debug` is loaded when this class is first required, then the value of this field is the `debug.setupvalue` of the Lua library by default.
`table`
  Method that serialize table values. If this field evaluates to `false` then table serialization is not allowed and results in Lua errors. By default, this field is a method that serialize the table contents including self-references and its meta-table accoding to the settings defined in the instance (see field `getmetatable`).
`thread`
  Method that serialize thread values. If this field evaluates to `false` then thread serialization is not allowed and results in Lua errors. By default, this field is `nil` thus thread serialization is not allowed.
`userdata`
  Method that serialize userdata values. If this field evaluates to `false` then userdata serialization is not allowed and results in Lua errors. By default, this field is a method that use the virtual meta-methods (i.e. fields defined by the object's meta-table but not used by the Lua VM) `__serialize` and `__load` to serialize and restore `userdata` values. See below for the behavior required by these meta-methods.

  `__serialize(udata)`
    Must return a string with a name that identifies this kind of `userdata`. The instance used to restore this value must map this name to a factory that creates such `userdata` values. This meta-method may also return additional values that will be used to restore the `userdata` state. These values may be any valid Lua value including the `userdata` itself (e.g. if it have self-references).
  `__load(udata, ...)`
    Receives a `userdata` value created by the factory registered in the instance with the name provided by meta-method `__serialize`. The factory must create empty `userdata` values which state will be restored by this meta-method using the additional values provided as arguments. Such arguments are the same additional values returned by meta-method `__serialize` at the moment the `userdata` was first serialized.

### Methods

`load(code)`
  Compiles the Lua chunk `code` that may contain chunks of serialized code. It also defines the proper environment of the loaded chunk so it can execute properly and recover serialized values. For example, to serialize and restore a sequence of values in order to produce a copy of the sequence you can use the following code:

      function makecopy(...)
        serial = loop.serial.Serializer()
        function serial:write(...)
          for i=1, select("#", ...) do
            self[#self+1] = select(i, ...)
          end
        end
        serial:serialize(...)
        return assert(serial:load("return "..table.concat(serial)))()
      end

`serialize(...)`
  Uses the `write` method to write a chunk of Lua code that is able to restore the values given as parameters. This code may be concatenated with other chunks of Lua code and then executed by method `load` to restore the values.
`write(...)` [required]
  Method used to write the resulting serialized code. It is called several times during the serialization process with sequences of strings as arguments that shall be concatenated to form the serialized code. By default, this field is `nil`.

### Meta-Fields

`__mode = "k"`
  Defines that serialized values registered are weak references thus such values are collected if they are not referenced elsewhere.

## Remarks

- Since it is only possible to manipulate upvalue contents, when functions that share the same upvalue are serialized and restored will actually refer to different upvalues although they store the same value.
- Each value is serialized only once by an instance of `Serializer`, therefore even if the value change the same old serialized code will be used. To produce new serialized chunks, use one instance per serialization.
- Each value is restored only once by an instance of `Serializer` thus all further references to the same value with the given instance will result in the same restored value. To produce new restored values, use one instance per restore.
- All the code produced by a instance of `Serializer` must be executed in the same order they were created and by a single instance of `Serializer` that may the different from the one used to produce the serialized code. In order to produce independent codes use one instance per serialization.

## Examples

### $ExampleDescription

    -- example missing

Copyright (C) 2004-2008 Tecgraf, PUC-Rio

This project is currently being maintained by Tecgraf at PUC-Rio.