Prototype based inheritance is used in many programming languages,
JavaScript being the most well known. As demonstrated in the solutions
this week there are a few different techniques that can be used.

lith provided a solution that merges the prototypes data into the
inheriting Hash when the prototype method is called. Special care is
taken to not overwrite fields in the inheriting Hash. This use of
`merge!` accomplishes that elegantly:

    def prototype=(prototype)
      merge!(prototype) {|k,o,n| o}
    end

Another feature of lith's solution is the ability to use blocks as
values in the Hash. This allows the objects to inherit methods as well
as simple values.

    starbucks = {:drink_size => 3, :cost => lambda {|this| this.drink_size + 1}}
    new_coffee_shop = {:drink_size => 1}
    new_coffee_shop.prototype = starbucks

In this case the new_coffee_shop's cost will be 2. It inherits the
cost method from the parent.

David Masover's solution used the JavaScript style of prototype
inheritance, where rather than merging the values of the parent into
the child object, the child object maintains a reference to the
parent. An advantage of this technique is that updates in the parent
are carried through to the child, unless the child overrides that
property. There is a trade off however, maintaining the link back to
the parent means an extra method lookup. This isn't usually an issue,
but if you are working with a deep nesting and inheriting many
attributes it can add up, so it's important to be aware of.

Thorsten Hater submitted a simple solution that maintained a reference
to a copy of the prototype object. This prevents modifications in the
prototype from being reflected in the child. The simplicity of the
implementation comes at a cost though, duplicating some objects may be
very expensive.

Matthias Reitinger also submitted a solution this week. Matthias's
solution extends OpenStruct to handle converting method calls into
hash keys. Like David's solution Matthias's solution maintains a
reference to the prototype object. In addition Matthias gives us a
`prototypes` method that returns an array of all the prototypes for
this object. This is used to detect a circular inheritance chain,
which almost always means an error. Matthias also adds a method to
delete a property. When a property is deleted from a child the child's
prototype's property will shine through.

There were several interesting takes on this week's quiz. Some of the
decisions, like whether to have fixed prototypes by copying/merging or
dynamic prototypes by maintaining references are mutually exclusive,
but other techniques from these solutions can be combined together,
like allowing blocks, deleting properties, or maintaining a list of
prototypes. When deciding which type of inheritance best fits your
next applications needs it is important to consider the trade offs
between simplicity and efficiency as well as speed and memory.

Thank you lith, David, Thorsten and Matthias for your solutions to
this week's quiz!