Class: Hashie::Dash

Inherits:
Hash
  • Object
show all
Includes:
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

Trash

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from PrettyInspect

#hashie_inspect, included

Methods inherited from Hash

#to_hash, #to_json

Methods included from HashExtensions

#hashie_stringify_keys, #hashie_stringify_keys!, included, #to_mash

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.


89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/hashie/dash.rb', line 89

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_properties_set!
end

Class Attribute Details

.defaultsObject (readonly)

Returns the value of attribute defaults


60
61
62
# File 'lib/hashie/dash.rb', line 60

def defaults
  @defaults
end

.propertiesObject (readonly)

Returns the value of attribute properties


60
61
62
# File 'lib/hashie/dash.rb', line 60

def properties
  @properties
end

.required_propertiesObject (readonly)

Returns the value of attribute required_properties


61
62
63
# File 'lib/hashie/dash.rb', line 61

def required_properties
  @required_properties
end

Class Method Details

.inherited(klass) ⇒ Object


67
68
69
70
71
72
73
# File 'lib/hashie/dash.rb', line 67

def self.inherited(klass)
  super
  (@subclasses ||= Set.new) << klass
  klass.instance_variable_set('@properties', self.properties.dup)
  klass.instance_variable_set('@defaults', self.defaults.dup)
  klass.instance_variable_set('@required_properties', self.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.


30
31
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
57
# File 'lib/hashie/dash.rb', line 30

def self.property(property_name, options = {})
  property_name = property_name.to_sym

  self.properties << property_name

  if options.has_key?(:default)
    self.defaults[property_name] = options[:default]
  elsif self.defaults.has_key?(property_name)
    self.defaults.delete property_name
  end

  unless instance_methods.map { |m| m.to_s }.include?("#{property_name}=")
    class_eval "def \#{property_name}(&block)\nself.[](\#{property_name.to_s.inspect}, &block)\nend\n\ndef \#{property_name}=(value)\nself.[]=(\#{property_name.to_s.inspect}, value)\nend\n"
  end

  if defined? @subclasses
    @subclasses.each { |klass| klass.property(property_name, options) }
  end
  required_properties << property_name if options.delete(:required)
end

.property?(name) ⇒ Boolean

Check to see if the specified property has already been defined.


77
78
79
# File 'lib/hashie/dash.rb', line 77

def self.property?(name)
  properties.include? name.to_sym
end

.required?(name) ⇒ Boolean

Check to see if the specified property is required.


83
84
85
# File 'lib/hashie/dash.rb', line 83

def self.required?(name)
  required_properties.include? name.to_sym
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).


110
111
112
113
114
115
116
117
118
119
120
# File 'lib/hashie/dash.rb', line 110

def [](property)
  assert_property_exists! property
  value = super(property.to_s)
  # 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.


124
125
126
127
128
# File 'lib/hashie/dash.rb', line 124

def []=(property, value)
  assert_property_required! property, value
  assert_property_exists! property
  super(property.to_s, value)
end

#replace(other_hash) ⇒ Object


130
131
132
133
134
135
# File 'lib/hashie/dash.rb', line 130

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