Module: SmartEnum::Attributes

Included in:
SmartEnum
Defined in:
lib/smart_enum/attributes.rb

Defined Under Namespace

Modules: ClassMethods Classes: Attribute

Constant Summary collapse

Boolean =
[TrueClass, FalseClass].freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



31
32
33
# File 'lib/smart_enum/attributes.rb', line 31

def self.included(base)
  base.extend(ClassMethods)
end

Instance Method Details

#attributesObject



74
75
76
# File 'lib/smart_enum/attributes.rb', line 74

def attributes
  @attributes ||= {}
end

#freeze_attributesObject



123
124
125
126
127
# File 'lib/smart_enum/attributes.rb', line 123

def freeze_attributes
  attributes.values.each(&:freeze)
  attributes.freeze
  self
end

#initialize(opts = {}) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/smart_enum/attributes.rb', line 78

def initialize(opts={})
  if block_given?
    fail "Block passed, but it would be ignored"
  end
  init_opts = ::SmartEnum::Utilities.symbolize_hash_keys(opts)
  if self.class.attribute_set.empty?
    fail "no attributes defined for #{self.class}"
  end
  self.class.attribute_set.each do |attr_name, attr_def|
    if (arg=init_opts.delete(attr_name))
      if attr_def.types.any?{|type| arg.is_a?(type) }
        # No coercion necessary
        attributes[attr_name] = arg
      elsif attr_def.coercer
        coerced_arg = attr_def.coercer.call(arg)
        if attr_def.types.none?{|type| coerced_arg.is_a?(type) }
          # Coercer didn't give correct type
          fail "coercer for #{attr_name} failed to coerce #{arg} to one of #{attr_def.types.inspect}.  Got #{coerced_arg}:#{coerced_arg.class} instead"
        end
        # Coercer worked
        attributes[attr_name] = coerced_arg
      else
        # Wrong type, no coercer passed
        fail "Attribute :#{attr_name} passed #{arg}:#{arg.class} in initializer, but needs #{attr_def.types.inspect} and has no coercer"
      end
    else
      if attr_def.types == Boolean
        # booleans should always be true or false, not nil
        attributes[attr_name] = false
      else
        # Nothing provided for this attr in init opts, set to nil
        # to make sure we always have a complete attributes hash.
        attributes[attr_name] = nil
      end
    end
  end
  if init_opts.any?
    fail "unrecognized options: #{init_opts.inspect}"
  end
end

#inspectObject



119
120
121
# File 'lib/smart_enum/attributes.rb', line 119

def inspect
  "#<#{self.class} #{attributes.map{|k,v| "#{k}: #{v.inspect}"}.join(", ")}>"
end