module PIM::ObjectBuilder

Constants

BUILD_OBJECT_CLASS_VAR

Name of variable to hold the class of the object to be built

Attributes

__param_names__[R]
__post_build_block__[R]

Public Instance Methods

build(*param_names, &pre_build_block) click to toggle source
# File pim.rb, line 3142
def build *param_names, &pre_build_block

  param_names += @__param_names__ if @__param_names__
  @__param_names__ = param_names
  builder_class = self

  define_method :build do |*values, &build_block|

    self.instance_exec(*values, &pre_build_block) if pre_build_block
    self.instance_exec(&build_block) unless build_block.nil?

    args = {}
    param_names.each do |param_name|
      param_name = Utils.to_sym(param_name)
      variable_name = Utils.to_instance_variable_name(param_name)
      variable_value = self.instance_variable_get(variable_name)
      args[param_name] = variable_value unless variable_value.nil?
    end

    build_class = self.class.const_get(BUILD_OBJECT_CLASS_VAR)
    build_object = build_class.new args

    post_build_block = builder_class.__post_build_block__
    build_object.instance_exec(self, &post_build_block) if post_build_block

    build_object

  end

end
Also aliased as: create_build
create_build(*param_names, &pre_build_block)
Alias for: build
create_param(param_name, opts = {})
Alias for: param
init_builder(&initialize_block) click to toggle source

Block to be called when creating new builder, i.e. the ‘initialize’ method

# File pim.rb, line 3039
def init_builder &initialize_block

  self.define_singleton_method :create_builder do |parent_builder|
    self.new(parent_builder)
  end

  self.define_method :initialize do |*values|
    self.instance_exec(*values, &initialize_block)
  end

end
param(param_name, opts = {}) click to toggle source

Method to define a ‘param’

# File pim.rb, line 3057
def param param_name, opts = {}, &param_block

  multi_value = opts[:multi_value]
  default_value = opts[:default_value]

  use_builder = opts[:use_builder]
  collect_in = opts[:collect_in]

  method_name = to_sym(param_name)
  variable_name = to_instance_variable_name(collect_in || param_name)

  @__param_names__ ||= []
  param_to_add = Utils.to_sym(collect_in || param_name)

  # Don't allow the same param multiple times, unless it is a 'collect_in' and a param_block is specified
  if @__param_names__.include?(param_to_add)
    raise "Param '#{param_to_add}' is already defined in Builder" if collect_in.nil? or param_block.nil?
  else
    @__param_names__ << param_to_add
  end

  define_method method_name do |*values, **kwargs, &build_block|

    if use_builder

      # Dynamically build values
      if use_builder.is_a?(Proc)
        builder = use_builder.call(self)
      elsif use_builder.respond_to?(:create_builder)
        builder = use_builder.create_builder(self)
      elsif use_builder.is_a?(Class)
        builder = use_builder.new
      end
      raise "Option 'use_builder' must either define a Builder class or a Proc creating a Builder instance" unless builder.respond_to?(:build)
      values = builder.send(:build, *values, &build_block)

    elsif not build_block.nil?

      # Set or add build_block
      if values.empty?
        values = build_block
      else
        values << build_block
      end

    end

    # Ensure, values is a single value, if necessary
    if not multi_value and values.is_a?(Array)
      if values.size == 0
        values = nil
      elsif values.size == 1
        values = values.first
      end
    end

    # Set default value, if necessary
    if values.nil? and not default_value.nil?
      values = default_value
    end

    # Check values
    values = self.instance_exec(*values, **kwargs, &param_block) if param_block

    # Set new values
    old_values = self.instance_variable_get(variable_name)
    unless values.nil?
      if collect_in
        new_values = (old_values || []) << values
      elsif old_values.nil?
        new_values = values
      else
        raise "Parameter '#{param_name}' must only be specified once"
      end
      self.instance_variable_set(variable_name, new_values)
    end

    new_values || old_values

  end
  private method_name

end
Also aliased as: create_param
post_build(&post_build_block) click to toggle source

Optional block to be executed on the built object, using the builder as single parameter

# File pim.rb, line 3052
def post_build &post_build_block
  @__post_build_block__ = post_build_block
end