module DSLKit::DSLAccessor

def dsl_accessor(name, *default, &block)

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

the accessor is read in the context of the current instance.
block _block_ is given as an argument, the block is executed everytime
_default_ array is used as the default value. If no default value but a
value it is used as a default value, if more than one value is given the
as argument it defaults to nil. If *default is given as a single
This method creates a dsl accessor named _name_. If nothing else is given
def dsl_accessor(name, *default, &block)
  variable = "@#{name}"
  define_method(name) do |*args|
    if args.empty?
      result = instance_variable_get(variable)
      if result.nil?
        if default.empty?
          block && instance_eval(&block)
        elsif default.size == 1
          default.first
        else
          default
        end
      else
        result
      end
    else
      instance_variable_set(variable, args.size == 1 ? args.first : args)
    end
  end
end

def dsl_reader(name, *default, &block)

#dsl_accessor but can only be read not set.
This method creates a dsl reader accessor, that behaves exactly like a
def dsl_reader(name, *default, &block)
  variable = "@#{name}"
  define_method(name) do |*args|
    if args.empty?
      result = instance_variable_get(variable)
      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