Module: BuilderPattern

Defined in:
lib/builder_pattern.rb

Overview

BuilderPattern module

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(klass) ⇒ Object

rubocop:disable Metrics/MethodLength because of class_eval



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/builder_pattern.rb', line 6

def self.included(klass)
  klass.class_eval do
    private_class_method :new

    def self.attr_mandatory(*fields)
      @__attr_mandatory ||= []
      @__attr_mandatory |= fields.map { |field| "@#{field}".to_sym }
    end

    def self.attr_optional(*fields)
      @__attr_optional ||= []
      @__attr_optional |= fields.map { |field| "@#{field}".to_sym }
    end

    def self.build(&block)
      new.build(&block)
    end
  end
end

Instance Method Details

#build {|collector| ... } ⇒ Object

rubocop:disable Metrics/MethodLength desired single method, readable enough rubocop:disable Metrics/AbcSize desired single method, readable enough

Yields:

  • (collector)

Raises:

  • (ArgumentError)


29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/builder_pattern.rb', line 29

def build
  collector = OpenStruct.new
  yield collector
  mandatory = self.class.ancestors.map do |level|
    level.instance_variable_get(:@__attr_mandatory)
  end
                  .compact.flatten.uniq
  allowed = self.class.ancestors.map do |level|
    level.instance_variable_get(:@__attr_optional)
  end
                .compact.flatten | mandatory
  # Migrate the state to instance variables
  collector.each_pair do |key, val|
    key = "@#{key}".to_sym
    unless allowed.include?(key)
      raise ArgumentError, "Unknown field #{key} used in build"
    end
    instance_variable_set(key, val)
  end
  fields = mandatory - instance_variables
  return self if fields.empty?
  raise ArgumentError, "Mandatory fields #{fields.join(', ')} not set"
end