--[[ Prototype Delegation and Cloning with Mixins Module H. Conrad Cunningham, Professor Computer and Information Science University of Mississippi 1234567890123456789012345678901234567890123456789012345678901234567890 2016-10-31: Completed first version 2016-11-02: Refined comments A prototype-based language does not natively have the concept of class. It just has objects. Instead of using a class to instantiate a new object, a program "copies" (or clones) an existing object --the prototype--and modifies the copy to have the needed attributes (variables) and operations (functions or methods). Each prototype consists of a collection of slots. Each slot is filled with either a data attribute or an operation In Lua, the "copying" can occur by either physically copying a variable or function closure reference into the new object's slot or by delegating unchanged slots back to the prototype object itself. Lua can use metaables and the __index metamethod to set up the delegation. This module provides two constructor functions, set up to use the method syntax. Prototype:new creates a new object with delegation of unchanged slots. Prototype:clone creates a new object that is a shallow copy of the prototype. --]] local Prototype = {} Prototype.__index = Prototype -- Constructor method "new" creates a new object with its fields -- and methods copied from the table "mixin" but with other -- references delegated to object "self". A call of "Prototype:new" -- creates a basic object that delegates to object Prototype. If -- "obj" has been created by this "new", then a call of "obj:new" -- creates a new object that delegates to "obj". function Prototype:new(mixin) mixin = mixin or {} local obj = { __index = self } for k, v in pairs(mixin) do if k ~= "__index" then obj[k] = v end end return setmetatable(obj,obj) end -- Constructor method "clone" creates a new object with the fields -- and methods copied from both object "self" and "mixin". -- It preserves the prototype delegation from "self". function Prototype:clone(mixin) mixin = mixin or {} local obj = {} for k, v in pairs(self) do obj[k] = v end for k, v in pairs(mixin) do if k ~= "__index" then obj[k] = v end end return setmetatable(obj,obj) end return Prototype