#!/usr/bin/env ruby

# Reproduce an anomaly in Ruby's built-in dbm library: When iterating
# over a DBM file, accessing a second dbm file's enumerator
# prematurely ends the first file's iteration.

require "dbm"
require "tmpdir"

system("ruby -v")         # => ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
puts DBM::VERSION         # => GDBM version 1.8.3. 10/15/2002 (built Nov 16 2014 17:21:58)

Dir.mktmpdir do |dir|

  # Given a DBM file with data
  dbm1_path =  File.join(dir, "dbm1")
  DBM.open(dbm1_path) do |dbm|
    dbm["1"] = "one"
    dbm["2"] = "two"
    dbm["3"] = "three"
  end
  dbm1 = DBM.open(dbm1_path)

  # And a DBM file with no data
  dbm2_path = File.join(dir, "dbm2")
  dbm2 = DBM.open(dbm2_path)

  # I can enumerate over all entries in the dbm file with data
  dbm1_enum = dbm1.each_value
  dbm1_enum.next
  dbm1_enum.next
  dbm1_enum.next

  # However, if I first start iterating over the dbm file with data
  dbm1_enum = dbm1.each_value
  source_row = dbm1_enum.next
  source_row = dbm1_enum.next

  # And then access the other dbm file's enumerator
  dbm2.first

  # Then the iteration over the first dbm file ends prematurely
  begin
    dbm1_enum.next
    raise "anomaly not reproduced"
  rescue StopIteration
    puts "anomaly reproduced"
  end

end
