code: function cache (signature, cache) {
      // validate signature
      var signature = getValidSignature(signature)
      // make sure cache is object
      cache = requireValidOptionalObject(cache)
      // create cache entry for module if it does not exist
      if (!defined(immutable.caches[signature.moduleName])) {
          immutable.caches[signature.moduleName] = {}
      }
      var moduleCaches = immutable.caches[signature.moduleName]
      // throw error if attempting to add multiple caching rules to the same method
      if (defined(moduleCaches[signature.methodName]) && !immutable.defaultAllowOverride) {
          throw new Error('cache error: cache rule already defined for '+signature)
      }
      // add caching rule
      moduleCaches[signature.methodName] = {
          cached: false,
          cache: cache,
      }
      // cache method if it exists
      doCacheForMethod(signature.signature)
      // return immutable
      return ImmutableCore
  }
docs: @function cache
  
  define cache rule for module method. cache rule will be stored in global
  caches register. if module method is not yet defined cache rule will be
  applied when the module method is defined.
  
  the cache object can include the following parameters:
  
  cacheClient - object conforming to require-valid-cache-client spect.
  if cacheClient is not defined then method will fall back
  to cacheClient defined on the module which in turn falls
  back to the global default cache client
  
  expire - expire time. non-positive integer will never expire
  
  keyMethod - function that will be called with args and method meta data
  on every module method call and must return the cache key.
  if not defined default key generation method will be used.
  
  keyParams - array of parameters from args to be used for generating key.
  
  an error will be thrown on attempt to add multiple cache rules to same
  method.
  
  @oaram {string} signature - moduleName.functionName to cache
  @param {object} cache - cache rules
  
  @returns {ImmutableCore}
  
  @throws {Error}