Method Cache
============

cachedIn
--------

The `cachedIn` property allows to specify the attribute where to store the
computed value::

    >>> import math
    >>> from zope.cachedescriptors import method

    >>> class Point:
    ... 
    ...     def __init__(self, x, y):
    ...         self.x, self.y = x, y
    ...
    ...     @method.cachedIn('_cache')
    ...     def distance(self, x, y):
    ...         print 'computing distance'
    ...         return math.sqrt((self.x - x)**2 + (self.y - y)**2)
    
    >>> point = Point(1.0, 2.0)   

The value is computed once::

    >>> point.distance(2, 2)
    computing distance
    1.0
    >>> point.distance(2, 2)
    1.0


Using different arguments calculates a new distance::

    >>> point.distance(5, 2)
    computing distance
    4.0
    >>> point.distance(5, 2)
    4.0


The data is stored at the given `_cache` attribute::

    >>> point._cache
    <BTrees.OOBTree.OOBTree object at 0x...>

    >>> list(sorted(point._cache.items()))
    [(((2, 2), ()), 1.0), (((5, 2), ()), 4.0)]


It is possible to exlicitly invalidate the data::

    >>> point.distance.invalidate(point, 5, 2)
    >>> point.distance(5, 2)
    computing distance
    4.0

Invalidating keys which are not in the cache, does not result in an error::


    >>> point.distance.invalidate(point, 47, 11)
