Dynamic Object Orientation

MOO-Code

Back in the olden days (1995-2000) I used to play in a programming language called MOO-Code. [1] "MOO" stands for "MUD, Object Oriented", so it's pretty safe to assume some amount of object-orientation is involved. MOO-Code is not a pure OO language – it contains several data types (integers, real numbers, strings, objects, errors, and lists) and a few built-in functions – however its treatment of objects is interesting: the database stores only objects, their "attributes" (special data), "properties" (general data), and "verbs" (methods). There are no classes – verbs are part of their object – instead each object has the attribute ".parent", which is a reference to its parent object. (A "duck" may be a child of the "generic duck", but that generic duck is still a real object you can interact with in the MOO.) When a verb is called that isn't defined on the object in question, or the built-in function pass() is called inside a verb, it walks the .parent hierarchy until it finds an object that does define the verb, and calls that (the special variable this is initialised in the verb as a reference to the original object, allowing for proper polymorphism).

This is a form of prototype-based programming – delegation.

Javascript

Javascript also uses the delegation flavour of prototype-based programming, based on the .prototype property. Not much more to say, really, except that the object that is used as a prototype in Javascript is rarely used as a first-class object, which can more often be the case in a MOO. (You never really touch Array.prototype except to modify the functionality of all Array objects.)

Ruby

Nobody would call Ruby a prototype-based language; however, when you peek under the hood it's easy to start seeing similarities. Ruby is quite strongly object-oriented, as very few values are not first class objects (methods can be captured as objects, kind of, but blocks can only be encapsulated in Proc or Lambda objects) – significantly, classes are themselves objects. Each object has a special reference to its class (and that, in turn, to its ancestors), which defines the methods that can be invoked on the object. It also supports multiple inheritance by allowing lightweight classes (modules) to be "mixed in" to an object or class's ancestor hierarchy. The runtime lookup of a method in Ruby is a lot like the delegation used by MOO-Code and Javascript, which allows for dynamic modification of class hierarchies and methods.

The difference is that the methods are defined in the class, not on the object. This is true even true of "singleton methods" – Ruby objects each have their own special class (called the "singleton class"), which only they implement, that holds methods defined "on" that object.

o = Object.new
def o.foo
  puts "FOO!"
end
o.foo                                                 # prints 'FOO!'
p( o.singleton_class )                                # prints '#<Class:#<Object:0x000000015729d8>>'
p( o.singleton_class.instance_methods.include? :foo ) # prints 'true'


thumbnail image

Matthew Kerwin

Published
Modified
License
CC BY-SA 4.0
Tags
development, javascript, ruby
I've written a lot of Ops stuff lately, let's try some Dev. There's no real point to this, just dumping some information about some approaches to the design of dynamic object-oriented programming languages.

Comments powered by Disqus