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.
-
.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!
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.
88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/hashie/dash.rb', line 88 def initialize(attributes = {}, &block) super(&block) self.class.defaults.each_pair do |prop, value| self[prop] = begin value.dup 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.
59 60 61 |
# File 'lib/hashie/dash.rb', line 59 def defaults @defaults end |
.properties ⇒ Object (readonly)
Returns the value of attribute properties.
59 60 61 |
# File 'lib/hashie/dash.rb', line 59 def properties @properties end |
.required_properties ⇒ Object (readonly)
Returns the value of attribute required_properties.
60 61 62 |
# File 'lib/hashie/dash.rb', line 60 def required_properties @required_properties end |
Class Method Details
.inherited(klass) ⇒ Object
66 67 68 69 70 71 72 |
# File 'lib/hashie/dash.rb', line 66 def self.inherited(klass) super (@subclasses ||= Set.new) << klass klass.instance_variable_set('@properties', properties.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.
:message - Specify custom error message for required property
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/hashie/dash.rb', line 32 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 unless instance_methods.map(&:to_s).include?("#{property_name}=") define_method(property_name) { |&block| self.[](property_name, &block) } property_assignment = property_name.to_s.concat('=').to_sym define_method(property_assignment) { |value| self.[]=(property_name, value) } end if defined? @subclasses @subclasses.each { |klass| klass.property(property_name, ) } end if .delete(:required) required_properties[property_name] = .delete(:message) || "is required for #{name}." else fail ArgumentError, 'The :message option should be used with :required option.' if .key?(:message) end end |
.property?(name) ⇒ Boolean
Check to see if the specified property has already been defined.
76 77 78 |
# File 'lib/hashie/dash.rb', line 76 def self.property?(name) properties.include? name end |
.required?(name) ⇒ Boolean
Check to see if the specified property is required.
82 83 84 |
# File 'lib/hashie/dash.rb', line 82 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).
109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/hashie/dash.rb', line 109 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.
123 124 125 126 127 |
# File 'lib/hashie/dash.rb', line 123 def []=(property, value) assert_property_required! property, value assert_property_exists! property super(property, value) end |
#merge(other_hash) ⇒ Object
129 130 131 132 133 134 135 |
# File 'lib/hashie/dash.rb', line 129 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
137 138 139 140 141 142 |
# File 'lib/hashie/dash.rb', line 137 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
144 145 146 147 148 149 |
# File 'lib/hashie/dash.rb', line 144 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
151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/hashie/dash.rb', line 151 def update_attributes!(attributes) initialize_attributes(attributes) self.class.defaults.each_pair do |prop, value| self[prop] = begin value.dup rescue TypeError value end if self[prop].nil? end assert_required_attributes_set! end |