Module: Tins::DSLAccessor

Included in:
Module
Defined in:
lib/tins/dslkit.rb

Overview

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.

Instance Method Summary collapse

Instance Method Details

#dsl_accessor(name, *default, &block) ⇒ Object

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 ].



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/tins/dslkit.rb', line 215

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_lazy_accessor(name) {|default| ... } ⇒ Symbol

The dsl_lazy_accessor method defines a lazy-loaded accessor method with a default block.

This method creates a dynamic accessor that initializes its value lazily when first accessed. It stores the default value as a block in an instance variable and evaluates it on first access. If a block is passed to the accessor, it sets the instance variable to that block for future use.

Parameters:

  • name (Object)

    the name of the accessor method to define

Yields:

  • (default)

    optional block that provides the default value for initialization

Returns:

  • (Symbol)

    returns name of the defined method.



255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/tins/dslkit.rb', line 255

def dsl_lazy_accessor(name, &default)
  variable = "@#{name}"
  define_method(name) do |*args, &block|
    if !block && args.empty?
      if instance_variable_defined?(variable)
        instance_eval(&instance_variable_get(variable))
      elsif default
        instance_eval(&default)
      end
    elsif block
      instance_variable_set(variable, block)
    else
      raise ArgumentError, '&block argument is required'
    end
  end
end

#dsl_reader(name, *default, &block) ⇒ Object

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



274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
# File 'lib/tins/dslkit.rb', line 274

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