Class: ShapeOf::Hash
Overview
Hash[key: Shape, …] denotes it is a hash of shapes with a very specific structure. Hash (without square brackets) is just a hash with any shape. This, along with Array, are the core components of this module. Note that the keys are converted to strings for comparison for both the shape and object provided.
Class Method Summary
collapse
Methods inherited from Shape
#initialize, required?
Constructor Details
This class inherits a constructor from ShapeOf::Shape
Class Method Details
.[](shape = {}) ⇒ Object
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
|
# File 'lib/shape_of.rb', line 188
def self.[](shape = {})
raise TypeError, "Shape must be Hash, was #{shape.class.name}" unless shape.instance_of? ::Hash
Class.new(self) do
@class_name = "#{superclass.name}[#{shape.map { |(k, v)| "#{k.to_s}: #{v.inspect}" }.join(', ')}]"
@shape = stringify_rb_hash_keys(shape)
@internal_class = superclass.instance_variable_get(:@internal_class)
def self.name
@class_name
end
def self.to_s
@class_name
end
def self.inspect
@class_name
end
def self.shape_of?(hash)
return false unless super
rb_hash = stringify_rb_hash_keys(hash)
rb_hash.keys.each do |key|
return false unless @shape.key?(key)
end
@shape.each do |key, shape|
return false unless rb_hash.key?(key) || shape.respond_to?(:required?) && !shape.required?
end
rb_hash.all? do |key, elem|
if @shape[key].respond_to? :shape_of?
@shape[key].shape_of? elem
elsif @shape[key].is_a? ::Array
Array[@shape[key]].shape_of? elem
elsif @shape[key].is_a? ::Hash
Hash[@shape[key]].shape_of? elem
elsif @shape[key].is_a? Class
elem.instance_of? @shape[key]
else
elem == @shape[key]
end
end
end
end
end
|
.shape_of?(object) ⇒ Boolean
184
185
186
|
# File 'lib/shape_of.rb', line 184
def self.shape_of?(object)
object.instance_of? @internal_class
end
|
.stringify_rb_hash_keys(rb_hash) ⇒ Object
240
241
242
|
# File 'lib/shape_of.rb', line 240
def self.stringify_rb_hash_keys(rb_hash)
rb_hash.to_a.map { |k, v| [k.to_s, v] }.to_h
end
|