Class: Hegel::Generators::HashGenerator

Inherits:
Hegel::Generator show all
Defined in:
lib/hegel/generators.rb,
sig/hegel.rbs

Overview

Hegel::Syntax::Methods#hashes. A Hash from keys drawing each key and values each value, with [min_size, max_size] entries, unbounded above by default. Uniqueness is judged on the key alone, matching Ruby's own Hash: a later draw with a key already present replaces nothing, so it is rejected the same way SetGenerator rejects a duplicate element.

Instance Method Summary collapse

Methods inherited from Hegel::Generator

#filter, #map

Constructor Details

#initialize(keys, values, min_size:, max_size:) ⇒ HashGenerator

Returns a new instance of HashGenerator.

Parameters:



351
352
353
354
355
356
357
# File 'lib/hegel/generators.rb', line 351

def initialize(keys, values, min_size:, max_size:)
  super()
  @keys = keys
  @values = values
  @min_size = min_size
  @max_size = max_size
end

Instance Method Details

#do_draw(tc) ⇒ Hash[untyped, untyped]

Parameters:

  • tc (Object)

Returns:

  • (Hash[untyped, untyped])

Raises:



359
360
361
362
363
364
365
366
367
368
369
370
371
# File 'lib/hegel/generators.rb', line 359

def do_draw(tc)
  raise Hegel::Error, "hashes: min_size must not be negative" if @min_size.negative?

  max_size = @max_size || LibHegel::HEGEL_COLLECTION_MAX_SIZE_UNBOUNDED
  raise Hegel::Error, "hashes: max_size < min_size" if max_size < @min_size

  tc.start_span(LibHegel::HEGEL_LABEL_MAP)
  begin
    draw_entries(tc, max_size)
  ensure
    tc.stop_span(discard: false)
  end
end

#draw_entries(tc, max_size) ⇒ Hash[untyped, untyped]

Parameters:

  • tc (Object)
  • max_size (Integer)

Returns:

  • (Hash[untyped, untyped])


375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
# File 'lib/hegel/generators.rb', line 375

def draw_entries(tc, max_size)
  collection = tc.new_collection(@min_size, max_size)
  begin
    result = {}
    while tc.collection_more(collection)
      key, value = draw_entry(tc)
      if result.key?(key)
        tc.collection_reject(collection)
      else
        result[key] = value
      end
    end
    result
  ensure
    tc.collection_free(collection)
  end
end

#draw_entry(tc) ⇒ [untyped, untyped]

Draws the key and its value as one unit inside a single HEGEL_LABEL_MAP_ENTRY span (the label table gives hashes one span per entry, not one per key and a second per value), so the shrinker can retry the whole pair together.

Parameters:

  • tc (Object)

Returns:

  • ([untyped, untyped])


397
398
399
400
401
402
# File 'lib/hegel/generators.rb', line 397

def draw_entry(tc)
  tc.start_span(LibHegel::HEGEL_LABEL_MAP_ENTRY)
  [@keys.do_draw(tc), @values.do_draw(tc)]
ensure
  tc.stop_span(discard: false)
end