Class: Julewire::Core::Serialization::DeepFreeze

Inherits:
Object
  • Object
show all
Defined in:
lib/julewire/core/serialization/deep_freeze.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(max_depth, trust_frozen:) ⇒ DeepFreeze

Returns a new instance of DeepFreeze.



52
53
54
55
# File 'lib/julewire/core/serialization/deep_freeze.rb', line 52

def initialize(max_depth, trust_frozen:)
  @max_depth = max_depth
  @trust_frozen = trust_frozen
end

Class Method Details

.call(value, max_depth: NORMALIZATION_MAX_DEPTH, trust_frozen: false, validate_symbol_keys: false) ⇒ Object



10
11
12
13
# File 'lib/julewire/core/serialization/deep_freeze.rb', line 10

def call(value, max_depth: NORMALIZATION_MAX_DEPTH, trust_frozen: false, validate_symbol_keys: false)
  validate_symbol_keys(value) if validate_symbol_keys
  new(max_depth, trust_frozen: trust_frozen).call(value)
end

.validate_symbol_hash(value) ⇒ Object

Raises:

  • (TypeError)


34
35
36
37
38
# File 'lib/julewire/core/serialization/deep_freeze.rb', line 34

def validate_symbol_hash(value)
  raise TypeError, "owned data must be a Hash" unless value.is_a?(Hash)

  validate_symbol_keys(value)
end

.validate_symbol_keys(value) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/julewire/core/serialization/deep_freeze.rb', line 15

def validate_symbol_keys(value)
  # WeakMap is identity-keyed and accepts new keys while enumerating,
  # so reachable containers form one finite work inventory without a
  # separate cycle-skip branch.
  containers = ObjectSpace::WeakMap.new
  containers[value] = nil if container?(value)
  containers.each_key do |current|
    if current.is_a?(Hash)
      current.each do |key, item|
        validate_symbol_key!(key)
        containers[item] = nil if container?(item)
      end
    else
      current.each { containers[it] = nil if container?(it) }
    end
  end
  value
end

Instance Method Details

#call(value) ⇒ Object



57
58
59
# File 'lib/julewire/core/serialization/deep_freeze.rb', line 57

def call(value)
  traverse(value) { |root, depth| freeze_value(root, depth) }
end