Class std.object

Prototype-based objects.

This module creates the root prototype object from which every other object is descended. There are no classes as such, rather new objects are created by cloning an existing object, and then changing or adding to the clone. Further objects can then be made by cloning the changed object, and so on.

Objects are cloned by simply calling an existing object, which then serves as a prototype from which the new object is copied.

Note that Object methods are stored in the __index field of their metatable, and so cannot also use __index to lookup references with square brackets. See std.container objects if you want to do that.

Prototype Chain

table
 `-> Object

Objects

std.object.Object Root object.

Functions

std.object.clone (obj, ...) Clone an Object.
std.object.mapfields (obj, src[, map={}]) Return obj with references to the fields of src merged in.
std.object.prototype (x) Type of an object, or primitive.

Metamethods

std.object:__call (...) Return a clone of this object, and its metatable.
std.object:__pairs () Return an in-order iterator over public object fields.
std.object:__tostring () Return a string representation of this object.


Objects

std.object.Object
Root object.

Changing the values of these fields in a new object will change the corresponding behaviour.

Fields:

  • _init table or function object initialisation (default {})
  • _functions table module functions omitted when cloned
  • _type string object name (default "Object")

See also:

Usage:

  •  -- `_init` can be a list of keys; then the unnamed `init_1` through
     -- `init_m` values from the argument table are assigned to the
     -- corresponding keys in `new_object`.
     local Process = Object {
       _type = "Process",
       _init = { "status", "out", "err" },
     }
     local process = Process {
       procs[pid].status, procs[pid].out, procs[pid].err, -- auto assigned
       command = pipeline[pid],                           -- manual assignment
     }
  •  -- Or it can be a function, in which the arguments passed to the
     -- prototype during cloning are simply handed to the `_init` function.
     local Bag = Object {
       _type = "Bag",
       _init = function (obj, ...)
         for e in std.elems {...} do
           obj[#obj + 1] = e
         end
         return obj
       end,
     }
     local bag = Bag ("function", "arguments", "sent", "to", "_init")

Functions

Methods
std.object.clone (obj, ...)
Clone an Object.

Objects are essentially tables of field_n = value_n pairs.

Normally new_object automatically shares a metatable with proto_object. However, field names beginning with "_" are private, and moved into the object metatable during cloning. So, adding new private fields to an object during cloning will result in a new metatable for new_object that also happens to contain a copy of all the entries from the proto_object metatable.

While clones of Object inherit all properties of their prototype, it's idiomatic to always keep separate tables for the module table and the root object itself: That way you can't mistakenly engage the slower clone-from-module-table process unnecessarily.

Parameters:

  • obj Object an object
  • ... a list of arguments if obj._init is a function, or a single table if obj._init is a table.

Returns:

    Object a clone of obj

See also:

Usage:

     local object = require "std.object"  -- module table
     local Object = object {}             -- root object
     local o = Object {
       field_1 = "value_1",
       method_1 = function (self) return self.field_1 end,
     }
     print (o.field_1)                    --> value_1
     o.field_2 = 2
     function o:method_2 (n) return self.field_2 + n end
     print (o:method_2 (2))               --> 4
     os.exit (0)
std.object.mapfields (obj, src[, map={}])
Return obj with references to the fields of src merged in.

More importantly, split the fields in src between obj and its metatable. If any field names begin with "_", attach a metatable to obj by cloning the metatable from src, and then copy the "private" _ prefixed fields there.

You might want to use this function to instantiate your derived object clones when the src._init is a function -- when src._init is a table, the default (inherited unless you overwrite it) clone method calls mapfields automatically. When you're using a function _init setting, clone doesn't know what to copy into a new object from the _init function's arguments... so you're on your own. Except that calling mapfields inside _init is safer than manually splitting src into obj and its metatable, because you'll pick up any fixes and changes when you upgrade stdlib.

Parameters:

  • obj table destination object
  • src table fields to copy int clone
  • map table key renames as {old_key=new_key, ...} (default {})

Returns:

    table obj with non-private fields from src merged, and a metatable with private fields (if any) merged, both sets of keys renamed according to map

Usage:

     myobject.mapfields = function (obj, src, map)
       object.mapfields (obj, src, map)
       ...
     end
std.object.prototype (x)
Type of an object, or primitive.

It's conventional to organise similar objects according to a string valued _type field, which can then be queried using this function.

Additionally, this function returns the results of ??? for file objects, or type otherwise.

Parameters:

  • x anything

Returns:

    string type of x

Usage:

     local Stack = Object {
       _type = "Stack",
    
       __tostring = function (self) ... end,
    
       __index = {
         push = function (self) ... end,
         pop  = function (self) ... end,
       },
     }
     local stack = Stack {}
     assert (stack:prototype () == getmetatable (stack)._type)
    
     local prototype = Object.prototype
     assert (prototype (stack) == getmetatable (stack)._type)
    
     local h = io.open (os.tmpname (), "w")
     assert (prototype (h) == io.type (h))
    
     assert (prototype {} == type {})

Metamethods

std.object:__call (...)
Return a clone of this object, and its metatable.

Private fields are stored in the metatable.

Parameters:

  • ... arguments for prototype's _init

Returns:

    Object a clone of the this object.

See also:

Usage:

     local Object = require "std.object" {} -- not a typo!
     new = Object {"initialisation", "elements"}
std.object:__pairs ()
Return an in-order iterator over public object fields.

Returns:

  1. function iterator function
  2. Object self

Usage:

    for k, v in std.pairs (anobject) do process (k, v) end
std.object:__tostring ()
Return a string representation of this object.

First the object type, and then between { and } a list of the array part of the object table (without numeric keys) followed by the remaining key-value pairs.

This function doesn't recurse explicity, but relies upon suitable __tostring metamethods in field values.

Returns:

    string stringified object representation

See also:

Usage:

    print (anobject)
generated by LDoc 1.4.3 Last updated 2018-09-03 17:48:42