# class Settingslogic

A simple settings solution using a YAML file. See README for more information.

### Public Class Methods

[](key) click to toggle source

    # File lib/settingslogic.rb, line 36
    def [](key)
      instance.fetch(key.to_s, nil)
    end

[]=(key, val) click to toggle source

    # File lib/settingslogic.rb, line 40
    def []=(key, val)
      # Setting[:key][:key2] = 'value' for dynamic settings
      val = new(val, source) if val.is_a? Hash
      instance.store(key.to_s, val)
      instance.create_accessor_for(key, val)
    end

get(key) click to toggle source

Enables Settings.get('nested.key.name') for dynamic access

    # File lib/settingslogic.rb, line 15
    def get(key)
      parts = key.split('.')
      curs = self
      while p = parts.shift
        curs = curs.send(p)
      end
      curs
    end

load!() click to toggle source

    # File lib/settingslogic.rb, line 47
    def load!
      instance
      true
    end

namespace(value = nil) click to toggle source

    # File lib/settingslogic.rb, line 28
    def namespace(value = nil)
      @namespace ||= value
    end

new(hash_or_file = self.class.source, section = nil) click to toggle source

Initializes a new settings object. You can initialize an object in any of the following ways:

    Settings.new(:application) # will look for config/application.yml
    Settings.new("application.yaml") # will look for application.yaml
    Settings.new("/var/configs/application.yml") # will look for /var/configs/application.yml
    Settings.new(:config1 => 1, :config2 => 2)

Basically if you pass a symbol it will look for that file in the configs directory of your rails app, if you are using this in rails. If you pass a string it should be an absolute path to your settings file. Then you can pass a hash, and it just allows you to access the hash via methods.

    # File lib/settingslogic.rb, line 94
    def initialize(hash_or_file = self.class.source, section = nil)
      #puts "new! #{hash_or_file}"
      case hash_or_file
      when nil
        raise Errno::ENOENT, "No file specified as Settingslogic source"
      when Hash
        self.replace hash_or_file
      else
        file_contents = open(hash_or_file).read
        hash = file_contents.empty? ? {} : YAML.load(ERB.new(file_contents).result).to_hash
        if self.class.namespace
          hash = hash[self.class.namespace] or return missing_key("Missing setting '#{self.class.namespace}' in #{hash_or_file}")
        end
        self.replace hash
      end
      @section = section || self.class.source  # so end of error says "in application.yml"
      create_accessors!
    end

reload!() click to toggle source

    # File lib/settingslogic.rb, line 52
    def reload!
      @instance = nil
      load!
    end

source(value = nil) click to toggle source

    # File lib/settingslogic.rb, line 24
    def source(value = nil)
      @source ||= value
    end

suppress_errors(value = nil) click to toggle source

    # File lib/settingslogic.rb, line 32
    def suppress_errors(value = nil)
      @suppress_errors ||= value
    end

### Public Instance Methods

[](key) click to toggle source

    # File lib/settingslogic.rb, line 123
    def [](key)
      fetch(key.to_s, nil)
    end

[]=(key,val) click to toggle source

    # File lib/settingslogic.rb, line 127
    def []=(key,val)
      # Setting[:key][:key2] = 'value' for dynamic settings
      val = self.class.new(val, @section) if val.is_a? Hash
      store(key.to_s, val)
      create_accessor_for(key, val)
    end

create_accessor_for(key, val=nil) click to toggle source

Use instance_eval/class_eval because they're actually more efficient than define_method{} stackoverflow.com/questions/185947/ruby-definemethod-vs-def bmorearty.wordpress.com/2009/01/09/fun-with-rubys-instance_eval-and-class_eval/

    # File lib/settingslogic.rb, line 152
      def create_accessor_for(key, val=nil)
        return unless key.to_s =~ /^\w+$/  # could have "some-setting:" which blows up eval
        instance_variable_set("@#{key}", val)
        self.class.class_eval <<-EndEval
          def #{key}
            return @#{key} if @#{key}
            return missing_key("Missing setting '#{key}' in #{@section}") unless has_key? '#{key}'
            value = fetch('#{key}')
            @#{key} = if value.is_a?(Hash)
              self.class.new(value, "'#{key}' section in #{@section}")
            elsif value.is_a?(Array) && value.all?{|v| v.is_a? Hash}
              value.map{|v| self.class.new(v)}
            else
              value
            end
          end
        EndEval
      end

create_accessors!() click to toggle source

This handles naming collisions with Sinatra/Vlad/Capistrano. Since these use a set() helper that defines methods in Object, ANY `method_missing` ANYWHERE picks up the Vlad/Sinatra settings! So settings.deploy_to title actually calls Object.deploy_to (from set :deploy_to, “host”), rather than the app_yml hash. Jeezus.

    # File lib/settingslogic.rb, line 143
    def create_accessors!
      self.each do |key,val|
        create_accessor_for(key)
      end
    end

method_missing(name, *args, &block) click to toggle source

Called for dynamically-defined keys, and also the first key deferenced at the top-level, if load! is not used. Otherwise, create_accessors! (called by new) will have created actual methods for each key.

    # File lib/settingslogic.rb, line 115
    def method_missing(name, *args, &block)
      key = name.to_s
      return missing_key("Missing setting '#{key}' in #{@section}") unless has_key? key
      value = fetch(key)
      create_accessor_for(key)
      value.is_a?(Hash) ? self.class.new(value, "'#{key}' section in #{@section}") : value
    end

missing_key(msg) click to toggle source

    # File lib/settingslogic.rb, line 186
    def missing_key(msg)
      return nil if self.class.suppress_errors

      raise MissingSetting, msg
    end

symbolize_keys() click to toggle source

    # File lib/settingslogic.rb, line 171
    def symbolize_keys

      inject({}) do |memo, tuple|

        k = (tuple.first.to_sym rescue tuple.first) || tuple.first

        v = k.is_a?(Symbol) ? send(k) : tuple.last # make sure the value is accessed the same way Settings.foo.bar works

        memo[k] = v && v.respond_to?(:symbolize_keys) ? v.symbolize_keys : v #recurse for nested hashes

        memo
      end

    end

to_hash() click to toggle source

Returns an instance of a Hash object

    # File lib/settingslogic.rb, line 135
    def to_hash
      Hash[self]
    end