Class: ShapeOf::Hash

Inherits:
Shape
  • Object
show all
Defined in:
lib/shape_of.rb

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

Raises:

  • (TypeError)


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].first].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

Returns:



184
185
186
# File 'lib/shape_of.rb', line 184

def self.shape_of?(object)
  object.instance_of? @internal_class
end