module ShallowAttributes::ClassMethods

Abstract class for value classes. Provides some helper methods for working with class methods.

@abstract

@since 0.1.0

Constants

DRY_TYPE_CLASS

Public Instance Methods

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

Define attribute with specific type and default value for current class.

@param [String, Symbol] name the attribute name @param [String, Symbol] type the type of attribute @param [hash] options the attribute options @option options [Object] :default default value for attribute @option options [Class] :of class of array elems @option options [boolean] :allow_nil cast `nil` to integer or float @option options [boolean] :present raise error if attribute was not provided

@example Create new User instance

class User
  include ShallowAttributes
  attribute :name, String, default: 'Anton'
end

User.new              # => #<User @attributes={:name=>"Anton"}, @name="Anton">
User.new(name: 'ben') # => #<User @attributes={:name=>"Ben"}, @name="Ben">

@return [Object]

@since 0.1.0

# File lib/shallow_attributes/class_methods.rb, line 86
def attribute(name, type, options = {})
  options[:default] ||= [] if type == Array

  default_values[name] = options.delete(:default)
  mandatory_attributes[name] = options.delete(:present)

  initialize_setter(name, type, options)
  initialize_getter(name)
end
attributes() click to toggle source

Returns all class attributes.

@example Create new User instance

class User
  include ShallowAttributes
  attribute :name, String
  attribute :last_name, String
  attribute :age, Integer
end

User.attributes # => [:name, :last_name, :age]

@return [Hash]

@since 0.1.0

# File lib/shallow_attributes/class_methods.rb, line 59
def attributes
  default_values.keys
end
default_values() click to toggle source

Returns hash that contains default values for each attribute

@private

@return [Hash] hash with default values

@since 0.1.0

# File lib/shallow_attributes/class_methods.rb, line 29
def default_values
  @default_values ||= {}
end
inherited(subclass) click to toggle source

Inject our default values into subclasses.

@private

@param [Object] subclass

Calls superclass method
# File lib/shallow_attributes/class_methods.rb, line 15
def inherited(subclass)
  super
  if respond_to?(:default_values)
    subclass.default_values.merge!(default_values)
  end
end
mandatory_attributes() click to toggle source

Returns hash that contains mandatory attributes

@private

@return [Hash] hash with mandatory attributes

@since 0.10.0

# File lib/shallow_attributes/class_methods.rb, line 40
def mandatory_attributes
  @mandatory_attributes ||= {}
end

Private Instance Methods

dry_type?(type) click to toggle source

Check type with dry-type

@private

@param [Class] type the class of type

@return [Bool]

@since 0.2.0

# File lib/shallow_attributes/class_methods.rb, line 151
def dry_type?(type)
  type.class.name.match(DRY_TYPE_CLASS)
end
initialize_getter(name) click to toggle source

Define getter method for each attribute.

@private

@param [String, Symbol] name the attribute name

@return [Object]

@since 0.1.0

# File lib/shallow_attributes/class_methods.rb, line 134
def initialize_getter(name)
  attr_reader name
end
initialize_setter(name, type, options) click to toggle source

Define setter method for each attribute.

@private

@param [String, Symbol] name the attribute name @param [String, Symbol] type the type of attribute @param [hash] options the attribute options

@return [Object]

@since 0.1.0

# File lib/shallow_attributes/class_methods.rb, line 109
    def initialize_setter(name, type, options)
      type_class = dry_type?(type) ? type.class : type

      module_eval <<-EOS, __FILE__, __LINE__ + 1
        def #{name}=(value)
          @#{name} = if value.is_a?(#{type_class}) && !value.is_a?(Array)
            value
          else
            #{type_casting(type, options)}
          end

          @attributes[:#{name}] = @#{name}
        end
      EOS
    end
type_casting(type, options) click to toggle source

Returns string for type casting

@private

@param [Class] type the class of type @param [Hash] options the options

@return [String]

@since 0.2.0

# File lib/shallow_attributes/class_methods.rb, line 165
def type_casting(type, options)
  if dry_type?(type)
    # yep, I know that it's terrible line but it was the easily
    # way to type cast data with dry-types from class method in instance method
    "ObjectSpace._id2ref(#{type.object_id})[value]"
  else
    "ShallowAttributes::Type.coerce(#{type}, value, #{options})"
  end
end