Class: DefinedHash
- Inherits:
-
Hash
- Object
- Hash
- DefinedHash
- Defined in:
- lib/defined_hash.rb
Overview
A hash with defined keys
This is somewhat similar to the ‘Dash’ provided by Hashie, but it has hashidator validations baked in, and in addition, supports the idea of optional columns. It also allows for sensible merging of such values. Property definition is based on the hashidator validation syntax.
Class Method Summary collapse
- .inherited(subclass) ⇒ Object
- .properties ⇒ Object
-
.property(name, type, opts = {}) ⇒ Object
Define a property for the hash.
- .property_names ⇒ Object
- .validations ⇒ Object
Instance Method Summary collapse
-
#[](name) ⇒ Object
Looks up a value from the hash.
-
#[]=(name, value) ⇒ Object
Assign a value to the hash.
-
#initialize(attributes = {}) ⇒ DefinedHash
constructor
A new instance of DefinedHash.
-
#merge!(hash) ⇒ self
Merges in another hash, destroying original values.
- #to_hash ⇒ Object
-
#valid? ⇒ Boolean
validates the hash with hashidator.
Constructor Details
#initialize(attributes = {}) ⇒ DefinedHash
Returns a new instance of DefinedHash.
19 20 21 22 23 |
# File 'lib/defined_hash.rb', line 19 def initialize(attributes={}) attributes.each do |name, value| self[name] = value end end |
Class Method Details
.inherited(subclass) ⇒ Object
146 147 148 149 |
# File 'lib/defined_hash.rb', line 146 def self.inherited(subclass) subclass.instance_variable_set('@properties', self.instance_variable_get('@properties').dup) unless self.instance_variable_get('@properties').nil? subclass.instance_variable_set('@validations', self.instance_variable_get('@validations').dup) unless self.instance_variable_get('@validations').nil? end |
.properties ⇒ Object
109 110 111 |
# File 'lib/defined_hash.rb', line 109 def self.properties (@properties || {}) end |
.property(name, type, opts = {}) ⇒ Object
Define a property for the hash
This is used to define the hash schema. Property definitions look somewhat similar to DataMapper ones, but the types actually define hashidator validation classes, as well as defining the schema.
90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/defined_hash.rb', line 90 def self.property(name, type, opts={}) # use a DefinedHash's inbuilt validations if we have a defined hash klass_validator = class_validator_for(type) klass_validator = (Array === klass_validator and Class === klass_validator.first and klass_validator.first < DefinedHash) ? [class_validator_for(klass_validator.first)] : klass_validator # optional validations done via proc validator = opts.fetch(:optional, false) ? proc { |v| v.nil? ? true : klass_validator } : klass_validator (@properties ||= {})[name] = type (@validations ||= {})[name] = validator nil end |
.property_names ⇒ Object
105 106 107 |
# File 'lib/defined_hash.rb', line 105 def self.property_names properties.keys.map { |p| p.to_s } end |
.validations ⇒ Object
113 114 115 |
# File 'lib/defined_hash.rb', line 113 def self.validations (@validations || {}) end |
Instance Method Details
#[](name) ⇒ Object
Looks up a value from the hash
32 33 34 35 36 37 38 39 40 |
# File 'lib/defined_hash.rb', line 32 def [](name) if Symbol === name super(name) elsif (self.class.property_names.include?(name.to_s)) super(name.to_s.to_sym) else nil end end |
#[]=(name, value) ⇒ Object
Assign a value to the hash
Assigns a value to the defined hash. This does a certain amount of typecasting, for example converting properties into arrays, or DefinedHashes
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/defined_hash.rb', line 54 def []=(name, value) if (property_name = self.class.property_names.detect { |pn| pn == name.to_s }) property_name = property_name.to_sym # we know it's a defined name, so this isn't a leak. property = self.class.properties[property_name] case property when Array value = self.class.typecast_value_to_array(property, value) if has_key?(property_name) self[property_name].concat( value ) else super(property_name, value) end when Class super(property_name, self.class.typecast_value_to_class(property, value)) else super(property_name, value) end end # ignore properties without names value end |
#merge!(hash) ⇒ self
Merges in another hash, destroying original values
131 132 133 134 135 136 |
# File 'lib/defined_hash.rb', line 131 def merge!(hash) hash.each do |key, value| self[key] = value end self end |
#to_hash ⇒ Object
138 139 140 141 142 143 144 |
# File 'lib/defined_hash.rb', line 138 def to_hash out = {} keys.each do |k| out[k] = self[k] end out end |
#valid? ⇒ Boolean
validates the hash with hashidator
122 123 124 |
# File 'lib/defined_hash.rb', line 122 def valid? Hashidator.validate(self.class.validations, self) end |