Class: SeeingIsBelieving::HashStruct

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/seeing_is_believing/hash_struct.rb

Defined Under Namespace

Classes: Attr

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(initial_values = {}, &initializer) ⇒ HashStruct

The aggressivenes of this is kind of annoying when you’re trying to build up a large hash of values maybe new vs new! one validates arg presence, maybe a separate #validate! method for that?



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/seeing_is_believing/hash_struct.rb', line 91

def initialize(initial_values={}, &initializer)
  initial_values.respond_to?(:each) ||
    raise(ArgumentError, "#{self.class.inspect} expects to be initialized with a hash-like object, but got #{initial_values.inspect}")
  @attributes = self
    .class
    .ancestors
    .take_while { |ancestor| ancestor != HashStruct }
    .map(&:init_blocks)
    .reverse
    .inject({}, :merge)
    .each_with_object({}) { |(name, block), attrs| attrs[name] = Attr.new(self, &block) }
  initial_values.each { |key, value| self[key] = value }
  initializer.call self if initializer
  each { } # access each key to see if it blows up
end

Class Method Details

.inspectObject



69
70
71
# File 'lib/seeing_is_believing/hash_struct.rb', line 69

def self.inspect
  name || "HashStruct.anon"
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?



178
179
180
181
182
183
184
185
186
187
188
# File 'lib/seeing_is_believing/hash_struct.rb', line 178

def ==(other)
  if equal? other
    true
  elsif other.kind_of? Hash
    to_h == other
  elsif other.respond_to?(:to_h)
    to_h == other.to_h
  else
    false
  end
end

#[](key) ⇒ Object



115
116
117
# File 'lib/seeing_is_believing/hash_struct.rb', line 115

def [](key)
  @attributes[internalize! key].value
end

#[]=(key, value) ⇒ Object



119
120
121
# File 'lib/seeing_is_believing/hash_struct.rb', line 119

def []=(key, value)
  @attributes[internalize! key] = Attr.new(self, value)
end

#each(&block) ⇒ Object



108
109
110
111
112
113
# File 'lib/seeing_is_believing/hash_struct.rb', line 108

def each(&block)
  return to_enum :each unless block
  @attributes.keys.each do |name|
    block.call(name, self[name])
  end
end

#fetch(key, ignored = nil) ⇒ Object



123
124
125
# File 'lib/seeing_is_believing/hash_struct.rb', line 123

def fetch(key, ignored=nil)
  self[key]
end

#hashObject

this might be pretty expensive



192
193
194
# File 'lib/seeing_is_believing/hash_struct.rb', line 192

def hash
  to_h.hash
end

#inspectObject



144
145
146
147
148
# File 'lib/seeing_is_believing/hash_struct.rb', line 144

def inspect
  classname = self.class.name ? "HashStruct #{self.class.name}" : self.class.inspect
  inspected_attrs = map { |k, v| "#{k}: #{v.inspect}" }.join(", ")
  "#<#{classname}: {#{inspected_attrs}}>"
end

#key?(key) ⇒ Boolean Also known as: has_key?, include?, member?

Returns:

  • (Boolean)


171
172
173
# File 'lib/seeing_is_believing/hash_struct.rb', line 171

def key?(key)
  key.respond_to?(:to_sym) && @attributes.key?(key.to_sym)
end

#keysObject



136
137
138
# File 'lib/seeing_is_believing/hash_struct.rb', line 136

def keys
  to_a.map(&:first)
end

#merge(overrides) ⇒ Object



132
133
134
# File 'lib/seeing_is_believing/hash_struct.rb', line 132

def merge(overrides)
  self.class.new(to_h.merge overrides)
end

#pretty_print(pp) ⇒ Object



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/seeing_is_believing/hash_struct.rb', line 150

def pretty_print(pp)
  pp.text self.class.name || 'HashStruct.anon { ... }'
  pp.text '.new('
  pp.group 2 do
    pp.breakable '' # place inside so that if we break, we are indented
    last_key = keys.last
    each do |key, value|
      # text-space-value, or text-neline-indent-value
      pp.text "#{key}:"
      pp.group 2 do
        pp.breakable " "
        pp.pp value
      end
      # all lines end in a comma, and can have a newline, except the last
      pp.comma_breakable unless key == last_key
    end
  end
  pp.breakable ''
  pp.text ')'
end

#to_hashObject Also known as: to_h



127
128
129
# File 'lib/seeing_is_believing/hash_struct.rb', line 127

def to_hash
  Hash[to_a]
end

#valuesObject



140
141
142
# File 'lib/seeing_is_believing/hash_struct.rb', line 140

def values
  to_a.map(&:last)
end