def configurable(symbol, &block)
      unless configurables[symbol]
        if config_contexts.key?(symbol)
          raise ReopenedConfigContextWithConfigurableError, "Cannot redefine config_context #{symbol} as a configurable value"
        end
        configurables[symbol] = Configurable.new(symbol)
        define_attr_accessor_methods(symbol)
      end
      if block
        yield(configurables[symbol])
      end
      configurables[symbol]
    end
def configurable(symbol, &block)
      unless configurables[symbol]
        if config_contexts.key?(symbol)
          raise ReopenedConfigContextWithConfigurableError, "Cannot redefine config_context #{symbol} as a configurable value"
        end
        configurables[symbol] = Configurable.new(symbol)
        define_attr_accessor_methods(symbol)
      end
      if block
        yield(configurables[symbol])
      end
      configurables[symbol]
    end
metaprogramming to set information about a config option.  This may be
 used in one of two ways:

 1. Block-based:
 configurable(:attr) do
   defaults_to 4
   writes_value { |value| 10 }
 end

 2. Chain-based:
 configurable(:attr).defaults_to(4).writes_value { |value| 10 }

 Currently supported configuration:

 defaults_to(value): value returned when configurable has no explicit value
 defaults_to BLOCK: block is run when the configurable has no explicit value
 writes_value BLOCK: block that is run to filter a value when it is being set

 === Parameters
 symbol<Symbol>:: Name of the config option
 default_value<Object>:: Default value [optional]
 block<Block>:: Logic block that calculates default value [optional]

 === Returns
 The value of the config option.