module Tins::DSLAccessor

The DSLAccessor module contains some methods, that can be used to make simple accessors for a DSL.

class CoffeeMaker
  extend Tins::Constant

  constant :on
  constant :off

  extend Tins::DSLAccessor

  dsl_accessor(:state) { off } # Note: the off constant from above is used

  dsl_accessor :allowed_states, :on, :off

  def process
    allowed_states.include?(state) or fail "Explode!!!"
    if state == on
      puts "Make coffee."
    else
      puts "Idle..."
    end
  end
end

cm = CoffeeMaker.new
cm.instance_eval do
  state      # => :off
  state on
  state      # => :on
  process    # => outputs "Make coffee."
end

Note that Tins::SymbolMaker is an alternative for Tins::Constant in this example. On the other hand SymbolMaker can make debugging more difficult.

Public Instance Methods

dsl_accessor(name, *default, &block) click to toggle source

This method creates a dsl accessor named name. If nothing else is given as argument it defaults to nil. If *default is given as a single value it is used as a default value, if more than one value is given the default array is used as the default value. If no default value but a block block is given as an argument, the block is executed everytime the accessor is read in the context of the current instance.

After setting up the accessor, the set or default value can be retrieved by calling the method name. To set a value one can call name :foo to set the attribute value to :foo or name(:foo, :bar) to set it to [ :foo, :bar ].

# File lib/tins/dslkit.rb, line 217
def dsl_accessor(name, *default, &block)
  variable = "@#{name}"
  define_method(name) do |*args|
    if args.empty?
      result =
        if instance_variable_defined?(variable)
          instance_variable_get(variable)
        end
      if result.nil?
        result = if default.empty?
          block && instance_eval(&block)
        elsif default.size == 1
          default.first
        else
          default
        end
        instance_variable_set(variable, result)
        result
      else
        result
      end
    else
      instance_variable_set(variable, args.size == 1 ? args.first : args)
    end
  end
end
dsl_reader(name, *default, &block) click to toggle source

This method creates a dsl reader accessor, that behaves exactly like a dsl_accessor but can only be read not set.

# File lib/tins/dslkit.rb, line 246
def dsl_reader(name, *default, &block)
  variable = "@#{name}"
  define_method(name) do |*args|
    if args.empty?
      result =
        if instance_variable_defined?(variable)
          instance_variable_get(variable)
        end
      if result.nil?
        if default.empty?
          block && instance_eval(&block)
        elsif default.size == 1
          default.first
        else
          default
        end
      else
        result
      end
    else
      raise ArgumentError, "wrong number of arguments (#{args.size} for 0)"
    end
  end
end