kigster/warp-dir

View on GitHub
lib/warp/dir/config.rb

Summary

Maintainability
A
0 mins
Test Coverage
A
97%
require 'forwardable'

module Warp
  module Dir
    class Config

      DEFAULTS = {
        warprc: "#{::Dir.home}/.warprc",
        shell: false,
        force: false,
        debug: false,
        no_color: false
      }

      attr_accessor :variables

      extend ::Forwardable
      def_delegators :@variables, :size, :<<, :map, :each
      def initialize(opts = {})
        configure(opts)
      end

      def configure(opts = {})
        options = DEFAULTS.merge(opts)

        # Move :config hash key->value to :warprc that is expected by the Config
        if options[:config]
          options[:warprc] = options[:config]
          options.delete(:config)
        end

        self.variables = []

        # OK. I concede. This is very likely a total overkill :O
        # The thing is: I just really like calling hash members via
        # methods, and I didn't want to load HashieMash because
        # it's big. Real big.
        #
        # IRB Session that explains it all:
        #
        # c = Config.new({ foo: "bar", bar: "foo"})
        # => #<Warp::Dir::Config:0x007ff8e39531f0 @variables=[:config, :foo, :bar], @config="/Users/kigster/.warprc", @foo="bar", @bar="foo">
        #  > c.foo              # => "bar"
        #  > c.bar              # => "foo"
        #  > c.bar?             # => true
        #  > c.config           # => "/Users/kigster/.warprc"
        #  > c.color = "red"    # => "red"
        #  > c.color            # => "red"
        #  > c.color?           # => true

        options.each_pair do |variable_name, value|
          self.variables << add_config_variable(variable_name, value)
        end
      end

      # allow syntax @config[:warprc]
      def [](key)
        self.send(key)
      end

      # Dispatches redis operations to master/slaves.
      def method_missing(method, *args, &block)
        if method =~ /=$/
          add_config_variable(method.to_s.gsub(/=$/, ''), *args)
        else
          super
        end
      end

      private

      def add_config_variable(variable_name, value)
        reader   = variable_name.to_sym
        writer   = "#{reader}=".to_sym
        boolean  = "#{reader}?"
        variable = "@#{reader}".to_sym
        # set this value on the the instance of config class
        instance_variable_set(variable, value)
        # add the reader and the writer to this key
        define_singleton_method(reader) { instance_variable_get(variable) }
        define_singleton_method(writer) { |new_value| instance_variable_set(variable, new_value) }
        define_singleton_method(boolean){ !instance_variable_get(variable).nil? }
        reader
      end

    end
  end
end