class Epuber::DSL::Attribute
Stores the information of an attribute. It also provides logic to implement any required logic.
Attributes
@return [Class] if defined it can be [Array] or [Hash]. It is used as default initialization value
and to automatically wrap other values to arrays.
@return [Object] if the attribute follows configuration over convention it can specify a default value.
@note The default value is not automatically wrapped and should be specified within the container
if any.
@return [Bool] whether the attribute describes file patterns.
@note This is mostly used by the linter.
@return [Bool] whether the attribute describes file patterns.
@note This is mostly used by the linter.
@return [Array, Hash] the list of the accepted keys for an attribute wrapped by a Hash.
@note A hash is accepted to group the keys associated only with certain keys (see the source
attribute of a Book).
@return [Symbol] name of attribute
@return [Bool] whether the specification should be considered invalid if a value for the attribute
is not specified.
@return [Bool] whether the specification should be considered invalid if a value for the attribute
is not specified.
@return [Bool] whether the attribute should be specified only on the root specification.
@return [Bool] whether the attribute should be specified only on the root specification.
@return [Bool] whether there should be a singular alias for the attribute writer.
@return [Bool] whether there should be a singular alias for the attribute writer.
@return [Array<Class>] the list of the classes of the values supported by the attribute writer.
If not specified defaults to [String].
Public Class Methods
Returns a new attribute initialized with the given options.
@param [Symbol] name
@see name
@raise If there are unrecognized options.
# File lib/epuber/dsl/attribute.rb, line 26 def initialize(name, inherited: false, root_only: false, required: false, singularize: false, file_patterns: false, container: nil, keys: nil, default_value: nil, auto_convert: {}, types: nil) @name = name @inherited = inherited @root_only = root_only @required = required @singularize = singularize @file_patterns = file_patterns @container = container @keys = keys @default_value = default_value @auto_convert = auto_convert @types = if !types.nil? types elsif @default_value && @auto_convert.empty? [@default_value.class] elsif !@auto_convert.empty? [@auto_convert.values.first] else [String] end end
Public Instance Methods
Converts value to compatible type of attribute
Can be configured with option :auto_convert
Supports conversion from type to type, eg `{ String => Fixnum }` also from types to type eg `{ [String, Date] => Fixnum }` Supports custom conversion with Proc, eg `{ String => lambda { |value| value.to_s } }` also with multiple types
# File lib/epuber/dsl/attribute.rb, line 218 def converted_value(value) begin validate_type(value) rescue StandardError raise if @auto_convert.nil? dest_class = @auto_convert[value.class] if dest_class.nil? array_keys = @auto_convert.select { |k, _v| k.is_a?(Array) } array_keys_with_type = array_keys.select { |k, _v| k.any? { |klass| value.class <= klass } } dest_class = array_keys_with_type.values.first if array_keys_with_type.count.positive? end if dest_class.respond_to?(:call) return dest_class.call(value) elsif dest_class.respond_to?(:parse) return dest_class.parse(value) elsif dest_class <= String return value.to_s elsif dest_class.respond_to?(:new) return dest_class.new(value) else raise StandardError, "Object/class #{dest_class} doesn't support any convert method (#call, .parse or implicit .new)" end end value end
@return [Bool] defines whether the attribute reader should join the values with the parent.
@note Attributes stored in wrappers are always inherited.
# File lib/epuber/dsl/attribute.rb, line 136 def inherited? !root_only? && @inherited end
@return [String] A string representation suitable for debugging.
# File lib/epuber/dsl/attribute.rb, line 69 def inspect "<#{self.class} name=#{name} types=#{types}>" end
@return [Array<Class>] the list of the classes of the values supported by the attribute, including
the container.
# File lib/epuber/dsl/attribute.rb, line 85 def supported_types @supported_types ||= @types.dup.push(container).compact end
@return [String] A string representation suitable for UI.
# File lib/epuber/dsl/attribute.rb, line 63 def to_s "Attribute `#{name}`" end
Validates a value before storing.
@raise If a root only attribute is set in a subspec.
@raise If a unknown key is added to a hash.
@return [void]
# File lib/epuber/dsl/attribute.rb, line 182 def validate_for_writing(spec, value) if root_only? && !spec.root? raise StandardError, "Can't set `#{name}` attribute for subspecs (in `#{spec.name}`)." end return unless keys # @return [Array] the flattened list of the allowed keys for the hash of a given specification. # allowed_keys = lambda do if keys.is_a?(Hash) keys.keys.concat(keys.values.flatten.compact) else keys end end value.each_key do |key| unless allowed_keys.include?(key) raise StandardError, "Unknown key `#{key}` for #{self}. Allowed keys: `#{allowed_keys.inspect}`" end end end
Validates the value for an attribute. This validation should be performed before the value is prepared or wrapped.
@note The this is called before preparing the value.
@raise If the type is not in the allowed list.
@return [void]
# File lib/epuber/dsl/attribute.rb, line 167 def validate_type(value) return if value.nil? return if supported_types.any? { |klass| value.class <= klass } raise StandardError, "Non acceptable type `#{value.class}` for #{self}. Allowed types: `#{types.inspect}`" end
@return [String] the name of the setter method for the attribute.
# File lib/epuber/dsl/attribute.rb, line 144 def writer_name "#{name}=" end
@return [String] an aliased attribute writer offered for convenience on the DSL
.
# File lib/epuber/dsl/attribute.rb, line 150 def writer_singular_form "#{name.to_s.singularize}=" if singularize? end