Class: Super::ReorderableHash

Inherits:
Object
  • Object
show all
Includes:
Enumerable, TSort
Defined in:
lib/super/reorderable_hash.rb

Constant Summary collapse

UNDEFINED =
BasicObject.new

Instance Method Summary collapse

Constructor Details

#initialize(data = {}) ⇒ ReorderableHash

Returns a new instance of ReorderableHash.



10
11
12
13
14
15
16
17
18
19
# File 'lib/super/reorderable_hash.rb', line 10

def initialize(data = {})
  @data = data
  @ordering = {}
  keys = @data.keys
  dependencies = []
  keys.each do |key|
    @ordering[key] = dependencies.dup
    dependencies.push(key)
  end
end

Instance Method Details

#[]=(key, where, value) ⇒ Object



58
59
60
# File 'lib/super/reorderable_hash.rb', line 58

def []=(key, where, value)
  insert(key, value, **where)
end

#eachObject



78
79
80
81
82
83
84
85
86
# File 'lib/super/reorderable_hash.rb', line 78

def each
  if !block_given?
    return enum_for(:each)
  end

  tsort_each do |key|
    yield key, @data[key]
  end
end

#insert(key, value, before: UNDEFINED, after: UNDEFINED) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
# File 'lib/super/reorderable_hash.rb', line 21

def insert(key, value, before: UNDEFINED, after: UNDEFINED)
  if @ordering.key?(key) || @data.key?(key)
    raise Super::Error::ReorderableHash::DuplicateKey, "Duplicate key: #{key}"
  end
  @ordering[key] = []
  @data[key] = value

  order(key, before: before, after: after)

  nil
end

#keysObject



62
63
64
# File 'lib/super/reorderable_hash.rb', line 62

def keys
  tsort
end

#order(key, before: UNDEFINED, after: UNDEFINED) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/super/reorderable_hash.rb', line 33

def order(key, before: UNDEFINED, after: UNDEFINED)
  if before != UNDEFINED
    if !@ordering.key?(before)
      raise KeyError, "Before key not found. Have: #{@data.keys} Requested: #{before}"
    end
    @ordering[before].push(key)
  end

  if after != UNDEFINED
    if !@ordering.key?(after)
      raise KeyError, "After key not found. Have: #{@data.keys} Requested: #{after}"
    end
    @ordering[key].push(after)
  end
end

#to_hObject



72
73
74
75
76
# File 'lib/super/reorderable_hash.rb', line 72

def to_h
  keys.each_with_object({}) do |key, hash|
    hash[key] = @data[key]
  end
end

#tsort_each_child(node, &block) ⇒ Object



53
54
55
56
# File 'lib/super/reorderable_hash.rb', line 53

def tsort_each_child(node, &block)
  dependencies = @ordering.fetch(node) { [] }
  dependencies.each(&block)
end

#tsort_each_node(&block) ⇒ Object



49
50
51
# File 'lib/super/reorderable_hash.rb', line 49

def tsort_each_node(&block)
  @ordering.each_key(&block)
end

#valuesObject



66
67
68
69
70
# File 'lib/super/reorderable_hash.rb', line 66

def values
  keys.each_with_object([]) do |key, array|
    array.push(@data[key])
  end
end