module Twigg::Settings::DSL::InstanceMethods
Public Class Methods
new(hash = nil)
click to toggle source
Calls superclass method
# File lib/twigg/settings/dsl.rb, line 61 def initialize(hash = nil) super deep_open_structify!(self) override_methods!(self, self.class.overrides) end
Private Instance Methods
deep_open_structify!(instance)
click to toggle source
Recursively replace nested hash values with OpenStructs.
This enables us to make nice calls like `Config.foo.bar` instead of the somewhat unsightly `Config.foo`.
# File lib/twigg/settings/dsl.rb, line 71 def deep_open_structify!(instance) # call `to_a` here to avoid mutating the collection during iteration instance.each_pair.to_a.each do |key, value| if value.is_a?(Hash) deep_open_structify!(instance.[]=(key, OpenStruct.new(value))) end end end
define_getter(instance, namespace, name, options)
click to toggle source
Defines a getter on the `instance` for setting `name` within `namespace`.
The getter:
- memoizes its result - raises an ArgumentError if the option is required by not configured - supplies a default value if the option is not configured and a default setting is available - optionally calls a supplied block to perform validation of the configured value
# File lib/twigg/settings/dsl.rb, line 124 def define_getter(instance, namespace, name, options) instance.define_singleton_method name do value = instance_variable_get("@#{namespace}__#{name}") return value if value if options[:required] && !instance.each_pair.to_a.map(&:first).include?(name) raise ArgumentError, "#{name} not set" end value = instance.[](name) || options[:default] options[:block].call(name, value) if options[:block] instance_variable_set("@#{namespace}__#{name}", value) end end
override_methods!(instance, overrides, namespace = nil)
click to toggle source
Recurses through the `overrides` hash, overriding OpenStruct-supplied methods with ones which handle defaults, perform validation, and memoize their results.
The `overrides` hash itself is built up using the DSL
as this class file is passed. This method is called at runtime, once the YAML file containing the configuration has been loaded from disk.
# File lib/twigg/settings/dsl.rb, line 87 def override_methods!(instance, overrides, namespace = nil) return unless overrides overrides.each do |name, options| if options.is_a?(Namespace) process_namespace(instance, namespace, name, options) # recurses else define_getter(instance, namespace, name, options) end end end
process_namespace(instance, namespace, name, options)
click to toggle source
Sets up the given `namespace` on `instance`, if not already set up, and (recursively) calls {#override_methods!} to set up `name`.
# File lib/twigg/settings/dsl.rb, line 101 def process_namespace(instance, namespace, name, options) nested = instance.[](name) unless nested.is_a?(OpenStruct) instance.[]=(name, nested = OpenStruct.new) end override_methods!(nested, options, name) end