Prototype Based Languages are ones where there are only objects, and no classes. Lua, Javascript, and lesser known languages like Io and Self, and to get technical, Python and Ruby (though they strongly advise you to ignore the man behind the curtain). To contrast, in C++ and Java, there's no real "Class Object", in the sense that the Class is really a declaration and wouldn't store any introspection information in memory. There's no "address" of a class object in C++, where as every table in Lua has an address. So, that's the difference from a technical standpoint.
However, and this is the point where I wasn't sure to move forward from, Classes offer features like "constructors." In lua, this is easy to get back. In kikito's middleclass library, it's the initialize function. However, that creates a subdivision between Classes and Instances, since only instances get initialized, and initializing a Class object in a hierarchy of inheritance is nonsensical. In a Prototype system, inheritance is called "cloning", and with objects that just clone each other, how would you construct those last objects? For a programmer, it would kind of mean manually building the specialized object at the point you use it, which sounds like a hassle and probably breaks any kind of encapsulation.
So, I did some research, and the best pattern I could see being used in prototype langauges, besides getting back to classes, is just to do function chaining. I'll demonstrate with some code:
Code: Select all
-- parent object of all objects
Object = {
clone = function( self, proto )
proto = proto or {}
proto.__index = self
return setmetatable(proto, proto)
end
}
-- Some container
Foo = Object:clone {
x = 27,
init = function(self, y)
self.y = y
return self
end
setX = function(self, x)
self.x = x
return self
end
}
-- Lacking any kind of constructor
bar = Foo:clone():init( 42 ):setX( 2993 )
print( Object, Foo, Foo.x, bar, bar.x, bar.y )