lib/configurations/configuration.rb in configurations-1.1.0 vs lib/configurations/configuration.rb in configurations-1.3.0
- old
+ new
@@ -57,25 +57,25 @@
# Method missing gives access for reading and writing to the underlying configuration hash via dot notation
#
def method_missing(method, *args, &block)
property = method.to_s[0..-2].to_sym
+ value = args.first
if _is_writer?(method) && @_writeable && _configurable?(property)
- _assert_type!(property, args.first)
- @configuration[property] = args.first
+ _assign!(property, value)
elsif !_is_writer?(method) && @_writeable || _configured?(method)
@configuration[method]
else
- super
+ ::Kernel.send(method, *args, &block)
end
end
# Respond to missing according to the method_missing implementation
#
def respond_to_missing?(method, include_private = false)
- is_setter?(method) || @_writeable || _configured?(method) || super
+ is_setter?(method) || @_writeable || _configured?(method) || ::Kernel.respond_to_missing?(method, include_private)
end
# Set the configuration to writeable or read only. Access to writer methods is only allowed within the
# configure block, this method is used to invoke writability for subconfigurations.
# @param [Boolean] data true if the configuration should be writeable, false otherwise
@@ -96,19 +96,26 @@
h
end
end
- private
-
# @param [Symbol] property The property to test for configurability
# @return [Boolean] whether the given property is configurable
#
def _configurable?(property)
_arbitrarily_configurable? or @configurable.has_key?(property)
end
+
+ # @return [Boolean] whether this configuration is arbitrarily configurable
+ #
+ def _arbitrarily_configurable?
+ @configurable.nil? or @configurable.empty?
+ end
+
+ private
+
# @param [Symbol] property The property to test for
# @return [Boolean] whether the given property has been configured
#
def _configured?(property)
@configuration.has_key?(property)
@@ -125,45 +132,67 @@
# Evaluates configurable properties and passes eventual hashes down to subconfigurations
#
def _evaluate_configurable!
return if _arbitrarily_configurable?
- @configurable.each do |k, type|
+ @configurable.each do |k, assertion|
if k.is_a?(::Hash)
k.each do |property, nested|
- @configuration[property] = Configuration.new(nil, _to_configurable_hash(nested, type))
+ @configuration[property] = Configuration.new(nil, _to_configurable_hash(nested, assertion))
end
end
end
end
# @param [Symbol, Hash, Array] value configurable properties, either single or nested
# @param [Class] type the type to assert, if any
# @return a hash with configurable values pointing to their types
#
- def _to_configurable_hash(value, type)
+ def _to_configurable_hash(value, assertion)
value = [value] unless value.is_a?(::Array)
- ::Hash[value.zip([type].flatten*value.size)]
+ ::Hash[value.zip([assertion].flatten*value.size)]
end
+ # Assigns a value after running the assertions
+ # @param [Symbol] property the property to type test
+ # @param [Any] value the given value
+ #
+ def _assign!(property, value)
+ v = _evaluate_block!(property, value)
+ value = v unless v.nil?
+ _assert_type!(property, value)
+ @configuration[property] = value
+ end
+
# Type assertion for configurable properties
# @param [Symbol] property the property to type test
# @param [Any] value the given value
# @raise [ConfigurationError] if the given value has the wrong type
#
def _assert_type!(property, value)
- return if _arbitrarily_configurable?
+ return unless _evaluable?(property, :type)
- expected_type = @configurable[property]
- return if expected_type.nil?
+ assertion = @configurable[property][:type]
+ ::Kernel.raise ConfigurationError, "Expected #{property} to be configured with #{expected_type}, but got #{value.class.inspect}", caller unless value.is_a?(assertion)
+ end
- ::Kernel.raise ConfigurationError, "Expected #{property} to be configured with #{expected_type}, but got #{value.class.inspect}", caller unless value.is_a?(expected_type)
+ # Block assertion for configurable properties
+ # @param [Symbol] property the property to type test
+ # @param [Any] value the given value
+ #
+ def _evaluate_block!(property, value)
+ return value unless _evaluable?(property, :block)
+
+ evaluation = @configurable[property][:block]
+ evaluation.call(value)
end
- # @return [Boolean] whether this configuration is arbitrarily configurable
+ # @param [Symbol] property The property to test for
+ # @param [Symbol] assertion_type The evaluation type type to test for
+ # @return [Boolean] whether the given property is assertable
#
- def _arbitrarily_configurable?
- @configurable.nil? or @configurable.empty?
+ def _evaluable?(property, evaluation)
+ @configurable and @configurable.has_key?(property) and @configurable[property].is_a?(::Hash) and @configurable[property].has_key?(evaluation)
end
# @param [Symbol] method the method to test for
# @return [Boolean] whether the given method is a writer
#