Class: SuperStruct

Inherits:
Object
  • Object
show all
Defined in:
app/support/super_struct.rb

Overview

SuperStruct is a utility class that wraps a hash in a Struct-like object, allowing access to hash keys as attributes. It supports deep nesting, enabling nested hashes to be converted into nested Structs.

This class also overrides the == method to provide custom equality logic, comparing the content of the wrapped hash and the structure of the underlying Struct definition.

Examples:

Basic Usage

hash = { name: 'John', age: 30 }
struct = SuperStruct.new(hash)
struct.name # => 'John'
struct.age  # => 30

Deep Struct

hash = { person: { name: 'John', age: 30 }, city: 'New York' }
struct = SuperStruct.new(hash, deep: true)
struct.person.name # => 'John'
struct.city        # => 'New York'

Equality

hash1 = { name: 'John', age: 30 }
hash2 = { name: 'John', age: 30 }
struct1 = SuperStruct.new(hash1)
struct2 = SuperStruct.new(hash2)
struct1 == struct2 # => true

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hash, deep: false) ⇒ SuperStruct

Initializes a new SuperStruct instance.

Parameters:

  • hash (Hash)

    The hash to wrap in a Struct.

  • deep (Boolean) (defaults to: false)

    Whether to recursively convert nested hashes into Structs.



40
41
42
43
# File 'app/support/super_struct.rb', line 40

def initialize(hash, deep: false)
  @deep = deep
  @instance = deep ? hash_to_deep_super_struct(hash) : build_const(hash).new(*hash.values)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name) ⇒ Object

Delegates method calls to the underlying Struct instance, except for ==.

Parameters:

  • method_name (Symbol)

    The name of the method being called.

  • args (Array)

    The arguments for the method.

  • block (Proc)

    An optional block for the method.



50
51
52
53
54
55
56
# File 'app/support/super_struct.rb', line 50

def method_missing(method_name, *, &)
  if method_name != :== && @instance.respond_to?(method_name)
    @instance.send(method_name, *, &)
  else
    super
  end
end

Instance Attribute Details

#instanceStruct (readonly)

Returns The underlying Struct instance.

Returns:

  • (Struct)

    The underlying Struct instance.



31
32
33
# File 'app/support/super_struct.rb', line 31

def instance
  @instance
end

Instance Method Details

#==(other) ⇒ Boolean

Compares two SuperStruct objects for equality.

Parameters:

  • other (SuperStruct)

    The other SuperStruct to compare.

Returns:

  • (Boolean)

    True if the content and structure are equal, false otherwise.



71
72
73
74
75
# File 'app/support/super_struct.rb', line 71

def ==(other)
  return false unless other.is_a?(SuperStruct)

  deep_to_h(@instance) == deep_to_h(other.instance)
end

#respond_to_missing?(method_name, include_private = false) ⇒ Boolean

Checks if the SuperStruct responds to a given method.

Parameters:

  • method_name (Symbol)

    The name of the method.

  • include_private (Boolean) (defaults to: false)

    Whether to include private methods.

Returns:

  • (Boolean)

    True if the method is supported, false otherwise.



63
64
65
# File 'app/support/super_struct.rb', line 63

def respond_to_missing?(method_name, include_private = false)
  (method_name != :== && @instance.respond_to?(method_name)) || super
end