Module: Tins::HashSymbolizeKeysRecursive

Extended by:
ThreadLocal
Defined in:
lib/tins/hash_symbolize_keys_recursive.rb

Overview

This module provides recursive symbolization of hash keys. It handles nested structures including hashes and arrays, with special handling for circular references to prevent infinite recursion.

Examples:

Basic usage

hash = { "name" => "John", "address" => { "street" => "123 Main St" } }
hash.symbolize_keys_recursive
# => { name: "John", address: { street: "123 Main St" } }

Handling circular references

hash = { "name" => "John" }
hash["self"] = hash  # Circular reference
hash.symbolize_keys_recursive(circular: "[Circular Reference]")
# => { name: "John", self: "[Circular Reference]" }

Instance Method Summary collapse

Methods included from ThreadLocal

instance_thread_local, thread_local

Instance Method Details

#_symbolize_keys_recursive(object, circular: nil) ⇒ Object (private)

Performs the actual recursive symbolization work

Parameters:

  • object (Object)

    The object to process

  • circular (Object) (defaults to: nil)

    The value to return for circular references

Returns:

  • (Object)

    The processed object with symbolized keys



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/tins/hash_symbolize_keys_recursive.rb', line 80

def _symbolize_keys_recursive(object, circular: nil)
  case
  when seen[object.__id__]
    object = circular
  when object.respond_to?(:to_hash)
    object = object.to_hash
    seen[object.__id__] = true
    new_object = object.class.new
    seen[new_object.__id__] = true
    object.each do |k, v|
      new_object[k.to_s.to_sym] = _symbolize_keys_recursive(v, circular: circular)
    end
    object = new_object
  when object.respond_to?(:to_ary)
    object = object.to_ary
    seen[object.__id__] = true
    new_object = object.class.new(object.size)
    seen[new_object.__id__] = true
    object.each_with_index do |v, i|
      new_object[i] = _symbolize_keys_recursive(v, circular: circular)
    end
    object = new_object
  end
  object
end

#symbolize_keys_recursive(circular: nil) ⇒ Hash, ...

Recursively converts all string keys in a hash (and nested hashes/arrays) to symbols. This method does not modify the original hash.

Examples:

Basic usage

{ "name" => "John", "age" => 30 }.symbolize_keys_recursive
# => { name: "John", age: 30 }

Nested structures

{
  "user" => {
    "name" => "John",
    "hobbies" => ["reading", "swimming"]
  }
}.symbolize_keys_recursive
# => { user: { name: "John", hobbies: ["reading", "swimming"] } }

Circular reference handling

hash = { "name" => "John" }
hash["self"] = hash
hash.symbolize_keys_recursive(circular: "[Circular]")
# => { name: "John", self: "[Circular]" }

Parameters:

  • circular (Object) (defaults to: nil)

    The value to use when encountering circular references. Defaults to nil, which means circular references will be ignored.

Returns:



50
51
52
53
54
55
# File 'lib/tins/hash_symbolize_keys_recursive.rb', line 50

def symbolize_keys_recursive(circular: nil)
  self.seen = {}
  _symbolize_keys_recursive(self, circular: circular)
ensure
  self.seen = nil
end

#symbolize_keys_recursive!(circular: nil) ⇒ Hash, ...

Recursively converts all string keys in a hash (and nested hashes/arrays) to symbols. This method modifies the original hash in place.

Examples:

Basic usage

hash = { "name" => "John", "age" => 30 }
hash.symbolize_keys_recursive!
# => { name: "John", age: 30 }
# hash is now modified in place

Parameters:

  • circular (Object) (defaults to: nil)

    The value to use when encountering circular references. Defaults to nil, which means circular references will be ignored.

Returns:



69
70
71
# File 'lib/tins/hash_symbolize_keys_recursive.rb', line 69

def symbolize_keys_recursive!(circular: nil)
  replace symbolize_keys_recursive(circular: circular)
end