Class: Hash

Inherits:
Object
  • Object
show all
Defined in:
lib/everythingrb/core/hash.rb

Overview

Extensions to Ruby’s core Hash class

These additions make working with hashes more convenient by adding conversion methods to different data structures and string formatting helpers.

Examples:

Converting to different structures

user = { name: "Alice", roles: ["admin"] }
user.to_struct    # => #<struct name="Alice", roles=["admin"]>
user.to_ostruct   # => #<OpenStruct name="Alice", roles=["admin"]>

# Filtering and joining hash entries
{ a: 1, b: nil, c: 3 }.join_map(", ") { |k, v| "#{k}:#{v}" if v }
# => "a:1, c:3"

Constant Summary collapse

EMPTY_STRUCT =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

A minimal empty struct for Ruby 3.2+ compatibility

Ruby 3.2 enforces stricter argument handling for Struct. This means trying to create a Struct from an empty Hash will result in an ArgumentError being raised. This is trying to keep a consistent experience with that version and newer versions.

Returns:

  • (Struct)

    A struct with a single nil-valued field

Struct.new(:_).new(nil)

Instance Method Summary collapse

Instance Method Details

#deep_freezeself

Recursively freezes self and all of its values

Examples:

{ user: { name: "Alice", roles: ["admin"] } }.deep_freeze
# => Hash and all nested structures are now frozen

Returns:

  • (self)

    Returns the frozen hash



146
147
148
149
# File 'lib/everythingrb/core/hash.rb', line 146

def deep_freeze
  each_value { |v| v.respond_to?(:deep_freeze) ? v.deep_freeze : v.freeze }
  freeze
end

#join_map(join_with = "") {|key, value| ... } ⇒ String

Combines filter_map and join operations

Examples:

{ a: 1, b: nil, c: 2, d: nil, e: 3 }.join_map(", ") { |k, v| "#{k}-#{v}" if v }
# => "a-1, c-2, e-3"

Without a block

{ a: 1, b: nil, c: 2 }.join_map(" ")
# => "a 1 b c 2"

Parameters:

  • join_with (String) (defaults to: "")

    The delimiter to join elements with (defaults to empty string)

Yields:

  • (key, value)

    Block that filters and transforms hash entries

Yield Parameters:

  • key (Object)

    The current key

  • value (Object)

    The current value

Returns:

  • (String)

    Joined string of filtered and transformed entries



51
52
53
54
55
# File 'lib/everythingrb/core/hash.rb', line 51

def join_map(join_with = "", &block)
  block = ->(kv_pair) { kv_pair.compact } if block.nil?

  filter_map(&block).join(join_with)
end

#to_istructData

Converts hash to an immutable Data structure

Examples:

hash = { person: { name: "Bob", age: 30 } }
data = hash.to_istruct
data.person.name # => "Bob"
data.class # => Data

Returns:

  • (Data)

    An immutable Data object with the same structure



68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/everythingrb/core/hash.rb', line 68

def to_istruct
  recurse = lambda do |input|
    case input
    when Hash
      input.to_istruct
    when Array
      input.map(&recurse)
    else
      input
    end
  end

  Data.define(*keys.map(&:to_sym)).new(*values.map { |value| recurse.call(value) })
end

#to_ostructOpenStruct

Converts hash to an OpenStruct recursively

Examples:

hash = { config: { api_key: "secret" } }
config = hash.to_ostruct
config.config.api_key # => "secret"

Returns:

  • (OpenStruct)

    An OpenStruct with methods matching hash keys



122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/everythingrb/core/hash.rb', line 122

def to_ostruct
  recurse = lambda do |value|
    case value
    when Hash
      value.to_ostruct
    when Array
      value.map(&recurse)
    else
      value
    end
  end

  OpenStruct.new(**transform_values { |value| recurse.call(value) })
end

#to_structStruct

Converts hash to a Struct recursively

Examples:

hash = { user: { name: "Alice", roles: ["admin"] } }
struct = hash.to_struct
struct.user.name # => "Alice"
struct.class # => Struct

Returns:

  • (Struct)

    A struct with methods matching hash keys



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/everythingrb/core/hash.rb', line 94

def to_struct
  # For Ruby 3.2, it raises if you attempt to create a Struct with no keys
  return EMPTY_STRUCT if RUBY_VERSION.start_with?("3.2") && empty?

  recurse = lambda do |value|
    case value
    when Hash
      value.to_struct
    when Array
      value.map(&recurse)
    else
      value
    end
  end

  Struct.new(*keys.map(&:to_sym)).new(*values.map { |value| recurse.call(value) })
end