docs: def get(self, path, default=_NoDefault, as_type=None, resolve_references=True):
          """
          Gets a value for the specified path.
  
          :param path: the configuration key to fetch a value for, steps
              separated by the separator supplied to the constructor (default
              ``.``)
          :param default: a value to return if no value is found for the
              supplied path (``None`` is allowed)
          :param as_type: an optional callable to apply to the value found for
              the supplied path (possibly raising exceptions of its own if the
              value can not be coerced to the expected type)
          :param resolve_references: whether to resolve references in values
          :return: the value associated with the supplied configuration key, if
              available, or a supplied default value if the key was not found
          :raises ConfigurationError: when no value was found for *path* and
              *default* was not provided or a reference could not be resolved
          """
          value = self._source
          steps_taken = []
          try:
              # walk through the values dictionary
              for step in path.split(self._separator):
                  steps_taken.append(step)
                  value = value[step]
  
              if as_type:
                  return as_type(value)
              elif isinstance(value, Mapping):
                  # create an instance of our current type, copying 'configured' properties / policies
                  namespace = type(self)(separator=self._separator, missing=self._missing)
                  namespace._source = value
                  # carry the root object from namespace to namespace, references are always resolved from root
                  namespace._root = self._root
                  return namespace
              elif resolve_references and isinstance(value, str):
                  # only resolve references in str-type values (the only way they can be expressed)
                  return self._resolve(value)
              else:
                  return value
          except ConfiguredReferenceError:
              # also a KeyError, but this one should bubble to caller
              raise
          except KeyError as e:
              if default is not _NoDefault:
                  return default
              else:
                  missing_key = self._separator.join(steps_taken)
                  raise NotConfiguredError('no configuration for key {}'.format(missing_key), key=missing_key) from e