Class: BlackHoleStruct

Inherits:
Object
  • Object
show all
Defined in:
lib/black_hole_struct.rb

Overview

BlackHoleStruct is a data structure similar to an OpenStruct, that allows infinite chaining of attributes or [autovivification](en.wikipedia.org/wiki/Autovivification).

Constant Summary collapse

VERSION =

Current version

"0.1.2"

Instance Method Summary collapse

Constructor Details

#initialize(hash = {}) ⇒ BlackHoleStruct

BlackHoleStruct can be optionally initialized with a Hash

Parameters:

  • hash (Hash) (defaults to: {})

    Initialize with a hash

Raises:

  • (ArgumentError)


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

def initialize(hash = {})
  raise ArgumentError, "Argument should be a Hash" unless hash.is_a?(Hash)

  @table = {}
  hash.each do |key, value|
    value = self.class.new(value) if value.is_a?(Hash)
    @table[key.to_sym] = value
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) ⇒ Object (private)



128
129
130
131
132
133
134
135
136
137
138
# File 'lib/black_hole_struct.rb', line 128

def method_missing(name, *args)
  if @table[name.to_sym]
    @table[name.to_sym]
  else
    if name[-1] == "="
      @table[name[0..-2].to_sym] = args.first
    else
      @table[name.to_sym] = self.class.new
    end
  end
end

Instance Method Details

#==(other) ⇒ Boolean Also known as: eql?

Two BlackHoleStruct are equal if they each contain the same number of keys and if each key-value pair is equal to the corresponding elements in the other BlackHoleStruct.

Parameters:

Returns:

  • (Boolean)


40
41
42
# File 'lib/black_hole_struct.rb', line 40

def ==(other)
  other.is_a?(self.class) && self.to_h == other.to_h
end

#[](key) ⇒ Object

Retrieves the value object corresponding to the key symbol.

Parameters:

  • key (Symbol)

Returns:

  • the value object or a BlackHoleStruct if nothing was found



23
24
25
# File 'lib/black_hole_struct.rb', line 23

def [](key)
  method_missing(key)
end

#[]=(key, value) ⇒ Object

Associates the value given by value with the key given by key.

Parameters:

  • key (Symbol)
  • value

Returns:

  • the value



31
32
33
# File 'lib/black_hole_struct.rb', line 31

def []=(key, value)
  method_missing("#{key}=", value)
end

#deep_merge(other_hash) ⇒ Object

Returns a new hash with self and other_hash merged recursively. It only merges Hash recursively.

Parameters:

  • other_hash (Hash)

Returns:

  • the final hash



80
81
82
# File 'lib/black_hole_struct.rb', line 80

def deep_merge(other_hash)
  self.dup.deep_merge!(other_hash)
end

#deep_merge!(other_hash) ⇒ Object

Same as deep_merge, but modifies self.

Parameters:

  • other_hash (Hash)

Returns:

  • the final hash



87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/black_hole_struct.rb', line 87

def deep_merge!(other_hash)
  other_hash.each_pair do |current_key, other_value|
    this_value = @table[current_key.to_sym]

    if (this_value.is_a?(Hash) || this_value.is_a?(self.class)) &&
      (other_value.is_a?(Hash) || other_value.is_a?(self.class))
      @table[current_key.to_sym] = this_value.deep_merge(other_value)
    else
      @table[current_key.to_sym] = other_value
    end
  end

  self
end

#delete_field(key) ⇒ Object

Deletes the key-value pair and returns the value from hsh whose key is equal to key. If the key is not found, returns an instance of BlackHoleStruct.

Parameters:

  • key (Symbol)


48
49
50
# File 'lib/black_hole_struct.rb', line 48

def delete_field(key)
  @table[key.to_sym] = self.class.new
end

#each_pair {|key, value| ... } ⇒ Object

Calls block once for each key in hsh, passing the key-value pair as parameters. if no block is given, an Enumerator is returned instead.

Yields:

  • (key, value)


55
56
57
# File 'lib/black_hole_struct.rb', line 55

def each_pair
  @table.each_pair
end

#inspectString Also known as: to_s

Return the contents of this instance as a string.

Returns:

  • (String)


114
115
116
117
118
# File 'lib/black_hole_struct.rb', line 114

def inspect
  "#<#{self.class}"
    .concat(@table.map { |k, v| " :#{k}=#{v.inspect}" }.join(" "))
    .concat(">")
end

#merge(other_hash) ⇒ Object

Returns a new hash with self and other_hash merged.

Parameters:

  • other_hash (Hash)

Returns:

  • the final hash



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

def merge(other_hash)
  self.dup.merge!(other_hash)
end

#merge!(other_hash) ⇒ Object Also known as: update

Same as merge, but modifies self.

Parameters:

  • other_hash (Hash)

Returns:

  • the final hash



69
70
71
72
73
# File 'lib/black_hole_struct.rb', line 69

def merge!(other_hash)
  # no deep merge
  @table = self.to_h.merge!(other_hash)
  self
end

#to_hHash

Converts self to the hash

Returns:

  • (Hash)


104
105
106
107
108
109
110
# File 'lib/black_hole_struct.rb', line 104

def to_h
  hash = {}
  @table.each do |key, value|
    hash[key] = value.is_a?(self.class) ? value.to_h : value
  end
  hash
end