module Epuber::DSL::AttributeSupport

Public Instance Methods

attribute(name, options = {}) click to toggle source

Method to create attribute for DSL object

@example

attribute :name
attribute :title, required: true, inherited: true

@param [Symbol] name attribute name @param [Hash] options

@see Attribute

@return nil

# File lib/epuber/dsl/attribute_support.rb, line 19
def attribute(name, options = {})
  attr = Attribute.new(name, **options)

  dsl_attributes[name] = attr

  define_method_attr(name, attr)
end
define_method_attr(name, attr) click to toggle source

@param [Symbol] name @param [Epuber::DSL::Attribute] attr

@return nil

# File lib/epuber/dsl/attribute_support.rb, line 52
def define_method_attr(name, attr)
  key = name

  # define normal getter
  define_method(key) do
    value = @attributes_values[key]

    if !value.nil?
      # has value -> return it
      value

    elsif attr.inherited? && respond_to?(:parent) && !parent.nil?
      # hasn't value –> try to find it in parent
      parent.send(key)

    elsif !attr.default_value.nil?
      # just return the default value
      attr.converted_value(attr.default_value)
    end
  end

  # define normal setter
  define_method(attr.writer_name) do |value|
    if attr.singularize?
      array_value = if value.is_a? Array
                      value
                    else
                      [value]
                    end

      mapped = array_value.map { |one_value| attr.converted_value(one_value) }

      @attributes_values[key] = mapped
    else
      begin
        @attributes_values[key] = attr.converted_value(value)
      rescue StandardError => e
        UI.warning("Invalid value `#{value}` for attribute `#{name}`, original error `#{e}`",
                   location: caller_locations[1])
      end
    end
  end

  return unless attr.singularize?

  # define singular methods
  singular_key = key.to_s.singularize.to_sym

  define_method(singular_key) do
    value = @attributes_values[key]

    if attr.singularize? && value.is_a?(Array)
      value.first
    else
      value
    end
  end

  define_method(attr.writer_singular_form) do |value|
    if attr.singularize?
      array_value = if value.is_a?(Array)
                      value
                    else
                      [value]
                    end

      @attributes_values[key] = array_value.map { |one_value| attr.converted_value(one_value) }
    else
      @attributes_values[key] = attr.converted_value(value)
    end
  end
end
dsl_attributes() click to toggle source

All DSL attributes

@return [Hash<Symbol, Attribute>]

# File lib/epuber/dsl/attribute_support.rb, line 31
def dsl_attributes
  @dsl_attributes ||= {}
end
find_root(instance) click to toggle source

@return [Object]

# File lib/epuber/dsl/attribute_support.rb, line 37
def find_root(instance)
  return unless instance.respond_to?(:parent)

  if instance.parent.nil?
    instance
  else
    find_root(instance.parent)
  end
end