Design Considerations
=====================

``options`` is not intended to replace every class's or method's
parameter passing mechanisms--just the most highly-optioned
ones that multiplex a package's functionality to a range of use
cases.  These are generally the highest-level, most outward-facing
classes, objects, and APIs.  They will generally have at
least four configuration variables (e.g. kwargs used to create,
configure, and define each instance).

In general, classes will define a set of methods that are "outwards
facing"--methods called by external code when consuming the class's
functionality. Those methods should generally expose their options through
``**kwargs``, creating a local variable (say ``opts``) that represents the sum
of all options in use--the full stack of call, instance, and class options,
including any present magical interpretations.

Internal class methods--the sort that are not generally called by external
code, and that by Python convention are often prefixed by an underscore
(``_``)--these generally do not need ``**kwargs``. They should accept their
options as a single variable (say ``opts`` again) that the externally-facing
methods will provide.

For example, if ``options`` didn't provide the nice formatting
function ``attrs``, we might have designed our own::

    def _attrs(self, opts):
        nicekeys = [ k for k in opts.keys() if not k.startswith('_') ]
        return ', '.join([ "{}={}".format(k, repr(opts[k])) for k in nicekeys ])

    def draw(self, **kwargs):
        opts = self.options.push(kwargs)
        print self._attrs(opts)

``draw()``, being the outward-facing API, accepts general arguments and
manages their stacking (by ``push``ing ``kwargs`` onto the instance options).
When the internal ``_attrs()`` method is called, it is handed a pre-digested
``opts`` package of options.

A nice side-effect of making this distinction: Whenever you see a method with
``**kwargs``, you know it's outward-facing. When you see a method with just
``opts``, you know it's internal.

Objects defined with ``options`` make excellent "callables."
Define the ``__call__`` method, and you have a very nice analog of
function calls.

``options`` has broad utility, but it's not for every class or
module. It best suits high-level front-end APIs that multiplex lots
of potential functionality, and wish/need to do it in a clean/simple
way. Classes for which the set of instance variables is small, or
functions/methods for which the set of known/possible parameters
is limited--these work just fine with classic Python calling
conventions. For those, ``options`` is overkill. "Horses for courses."

