Class: Hashie::Dash
- Includes:
- Extensions::PrettyInspect
- Defined in:
- lib/hashie/dash.rb
Overview
A Dash is a 'defined' or 'discrete' Hash, that is, a Hash that has a set of defined keys that are accessible (with optional defaults) and only those keys may be set or read.
Dashes are useful when you need to create a very simple lightweight data object that needs even fewer options and resources than something like a DataMapper resource.
It is preferrable to a Struct because of the in-class API for defining properties as well as per-property defaults.
Direct Known Subclasses
Class Attribute Summary collapse
-
.defaults ⇒ Object
readonly
Returns the value of attribute defaults.
-
.getters ⇒ Object
readonly
Returns the value of attribute getters.
-
.properties ⇒ Object
readonly
Returns the value of attribute properties.
-
.required_properties ⇒ Object
readonly
Returns the value of attribute required_properties.
Class Method Summary collapse
- .inherited(klass) ⇒ Object
-
.property(property_name, options = {}) ⇒ Object
Defines a property on the Dash.
-
.property?(name) ⇒ Boolean
Check to see if the specified property has already been defined.
-
.required?(name) ⇒ Boolean
Check to see if the specified property is required.
Instance Method Summary collapse
-
#[](property) ⇒ Object
Retrieve a value from the Dash (will return the property's default value if it hasn't been set).
-
#[]=(property, value) ⇒ Object
Set a value on the Dash in a Hash-like way.
-
#initialize(attributes = {}, &block) ⇒ Dash
constructor
You may initialize a Dash with an attributes hash just like you would many other kinds of data objects.
- #merge(other_hash) ⇒ Object
- #merge!(other_hash) ⇒ Object
- #replace(other_hash) ⇒ Object
- #update_attributes!(attributes) ⇒ Object
Methods included from Extensions::PrettyInspect
Methods inherited from Hash
Methods included from Extensions::StringifyKeys
#stringify_keys, #stringify_keys!
Methods included from Extensions::StringifyKeys::ClassMethods
#stringify_keys, #stringify_keys!, #stringify_keys_recursively!
Constructor Details
#initialize(attributes = {}, &block) ⇒ Dash
You may initialize a Dash with an attributes hash just like you would many other kinds of data objects.
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/hashie/dash.rb', line 104 def initialize(attributes = {}, &block) super(&block) self.class.defaults.each_pair do |prop, value| self[prop] = begin val = value.dup if val.is_a?(Proc) val.arity == 1 ? val.call(self) : val.call else val end rescue TypeError value end end initialize_attributes(attributes) assert_required_attributes_set! end |
Class Attribute Details
.defaults ⇒ Object (readonly)
Returns the value of attribute defaults.
60 61 62 |
# File 'lib/hashie/dash.rb', line 60 def defaults @defaults end |
.getters ⇒ Object (readonly)
Returns the value of attribute getters.
61 62 63 |
# File 'lib/hashie/dash.rb', line 61 def getters @getters end |
.properties ⇒ Object (readonly)
Returns the value of attribute properties.
60 61 62 |
# File 'lib/hashie/dash.rb', line 60 def properties @properties end |
.required_properties ⇒ Object (readonly)
Returns the value of attribute required_properties.
62 63 64 |
# File 'lib/hashie/dash.rb', line 62 def required_properties @required_properties end |
Class Method Details
.inherited(klass) ⇒ Object
69 70 71 72 73 74 75 76 |
# File 'lib/hashie/dash.rb', line 69 def self.inherited(klass) super (@subclasses ||= Set.new) << klass klass.instance_variable_set('@properties', properties.dup) klass.instance_variable_set('@getters', getters.dup) klass.instance_variable_set('@defaults', defaults.dup) klass.instance_variable_set('@required_properties', required_properties.dup) end |
.property(property_name, options = {}) ⇒ Object
Defines a property on the Dash. Options are as follows:
:default - Specify a default value for this property, to be returned before a value is set on the property in a new Dash.
:required - Specify the value as required for this property, to raise an error if a value is unset in a new or existing Dash. If a Proc is provided, it will be run in the context of the Dash instance. If a Symbol is provided, the property it represents must not be nil. The property is only required if the value is truthy.
:message - Specify custom error message for required property
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/hashie/dash.rb', line 36 def self.property(property_name, = {}) properties << property_name if .key?(:default) defaults[property_name] = [:default] elsif defaults.key?(property_name) defaults.delete property_name end define_getter_for(property_name) define_setter_for(property_name) @subclasses.each { |klass| klass.property(property_name, ) } if defined? @subclasses condition = .delete(:required) if condition = .delete(:message) || "is required for #{name}." required_properties[property_name] = { condition: condition, message: } elsif .key?(:message) raise ArgumentError, 'The :message option should be used with :required option.' end end |
.property?(name) ⇒ Boolean
Check to see if the specified property has already been defined.
80 81 82 |
# File 'lib/hashie/dash.rb', line 80 def self.property?(name) properties.include? name end |
.required?(name) ⇒ Boolean
Check to see if the specified property is required.
86 87 88 |
# File 'lib/hashie/dash.rb', line 86 def self.required?(name) required_properties.key? name end |
Instance Method Details
#[](property) ⇒ Object
Retrieve a value from the Dash (will return the property's default value if it hasn't been set).
130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/hashie/dash.rb', line 130 def [](property) assert_property_exists! property value = super(property) # If the value is a lambda, proc, or whatever answers to call, eval the thing! if value.is_a? Proc self[property] = value.call # Set the result of the call as a value else yield value if block_given? value end end |
#[]=(property, value) ⇒ Object
Set a value on the Dash in a Hash-like way. Only works on pre-existing properties.
144 145 146 147 148 |
# File 'lib/hashie/dash.rb', line 144 def []=(property, value) assert_property_required! property, value assert_property_exists! property super(property, value) end |
#merge(other_hash) ⇒ Object
150 151 152 153 154 155 156 |
# File 'lib/hashie/dash.rb', line 150 def merge(other_hash) new_dash = dup other_hash.each do |k, v| new_dash[k] = block_given? ? yield(k, self[k], v) : v end new_dash end |
#merge!(other_hash) ⇒ Object
158 159 160 161 162 163 |
# File 'lib/hashie/dash.rb', line 158 def merge!(other_hash) other_hash.each do |k, v| self[k] = block_given? ? yield(k, self[k], v) : v end self end |
#replace(other_hash) ⇒ Object
165 166 167 168 169 170 |
# File 'lib/hashie/dash.rb', line 165 def replace(other_hash) other_hash = self.class.defaults.merge(other_hash) (keys - other_hash.keys).each { |key| delete(key) } other_hash.each { |key, value| self[key] = value } self end |
#update_attributes!(attributes) ⇒ Object
172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/hashie/dash.rb', line 172 def update_attributes!(attributes) update_attributes(attributes) self.class.defaults.each_pair do |prop, value| next unless self[prop].nil? self[prop] = begin value.dup rescue TypeError value end end assert_required_attributes_set! end |