black_hole_struct 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +37 -0
- data/lib/black_hole_struct.rb +103 -0
- data/test/black_hole_struct_test.rb +106 -0
- metadata +77 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 73a1e2099462587da0f479f244188535c3a237bd
|
4
|
+
data.tar.gz: e664723785a1fee9b05b29593a1ee481743d2298
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 54e70fa218aacd903f040a52112eaad60eb22e1561c6ffd502e6dc5ed53100967bc20e955d9fd93e3b53d3839751fe8fce3b0f2b8c0bda785ce5327a663d6eb7
|
7
|
+
data.tar.gz: 017822bce9972ef9cb83d7b6ed052eea09678ce9cd69bb33e7a5e6551be5262613d78384758d72d29a682b4decb5e1602655c304262890b9e35651070e8e246b
|
data/README.md
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# BlackHoleStruct
|
2
|
+
|
3
|
+
**BlackHoleStruct** is a data structure similar to an `OpenStruct`, that allows
|
4
|
+
infinite chaining of attributes or [autovivification](https://en.wikipedia.org/wiki/Autovivification).
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add it to your Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem "black-hole-struct"
|
12
|
+
```
|
13
|
+
|
14
|
+
Or install the gem manually:
|
15
|
+
|
16
|
+
```sh
|
17
|
+
$ gem install black-hole-struct
|
18
|
+
```
|
19
|
+
|
20
|
+
## Basic Usage
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
require "black_hole_struct"
|
24
|
+
|
25
|
+
config = BlackHoleStruct.new
|
26
|
+
config.dashboard.theme = "white"
|
27
|
+
config.dashboard.time.from = "now-1h"
|
28
|
+
config.dashboard.time.to = "now"
|
29
|
+
|
30
|
+
puts config.dashboard.theme # "white"
|
31
|
+
puts config.dashboard.time # #<BlackHoleStruct :from="now-1h" :to="now">
|
32
|
+
puts config.dashboard.time.from # "now-1h"
|
33
|
+
```
|
34
|
+
|
35
|
+
### Advanced usage
|
36
|
+
|
37
|
+
Check the [documentation](http://www.rubydoc.info/github/mickey/black-hole-struct/master/BlackHoleStruct).
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# *BlackHoleStruct* is a data structure similar to an OpenStruct, that allows
|
2
|
+
# infinite chaining of attributes or [autovivification](https://en.wikipedia.org/wiki/Autovivification).
|
3
|
+
class BlackHoleStruct
|
4
|
+
# Current version
|
5
|
+
VERSION = "0.1.0"
|
6
|
+
|
7
|
+
# BlackHoleStruct can be optionally initialized with a Hash
|
8
|
+
# @param [Hash] hash Initialize with a hash
|
9
|
+
# @return [BlackHoleStruct]
|
10
|
+
def initialize(hash = {})
|
11
|
+
raise ArgumentError, "Argument should be a Hash" unless hash.is_a?(Hash)
|
12
|
+
|
13
|
+
@table = {}
|
14
|
+
hash.each do |key, value|
|
15
|
+
value = self.class.new(value) if value.is_a?(Hash)
|
16
|
+
@table[key.to_sym] = value
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Retrieves the value object corresponding to the key symbol.
|
21
|
+
# @param [Symbol] key
|
22
|
+
# @return the value object or a BlackHoleStruct if nothing was found
|
23
|
+
def [](key)
|
24
|
+
method_missing(key)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Associates the value given by value with the key given by key.
|
28
|
+
# @param [Symbol] key
|
29
|
+
# @param value
|
30
|
+
# @return the value
|
31
|
+
def []=(key, value)
|
32
|
+
method_missing("#{key}=", value)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Two BlackHoleStruct are equal if they each contain the same number of keys
|
36
|
+
# and if each key-value pair is equal to the corresponding elements in
|
37
|
+
# the other BlackHoleStruct.
|
38
|
+
# @param [BlackHoleStruct]
|
39
|
+
# @return [Boolean]
|
40
|
+
def ==(other)
|
41
|
+
other.is_a?(self.class) && self.to_h == other.to_h
|
42
|
+
end
|
43
|
+
alias :eql? :==
|
44
|
+
|
45
|
+
# Deletes the key-value pair and returns the value from hsh whose key is equal to key.
|
46
|
+
# If the key is not found, returns an instance of BlackHoleStruct.
|
47
|
+
# @param [Symbol] key
|
48
|
+
def delete_field(key)
|
49
|
+
@table[key.to_sym] = self.class.new
|
50
|
+
end
|
51
|
+
|
52
|
+
# Calls block once for each key in hsh, passing the key-value pair as parameters.
|
53
|
+
# if no block is given, an Enumerator is returned instead.
|
54
|
+
# @yield [key, value]
|
55
|
+
def each_pair
|
56
|
+
@table.each_pair
|
57
|
+
end
|
58
|
+
|
59
|
+
# Adds the contents of other_hash to hsh.
|
60
|
+
# If no block is specified, entries with duplicate keys are overwritten with the values from other_hash,
|
61
|
+
# otherwise the value of each duplicate key is determined by calling the block with the key,
|
62
|
+
# its value in hsh and its value in other_hash.
|
63
|
+
# @param [Hash] other_hash
|
64
|
+
# @return the final hash
|
65
|
+
def merge!(other_hash)
|
66
|
+
# no deep merge
|
67
|
+
@table = self.to_h.merge!(other_hash)
|
68
|
+
end
|
69
|
+
alias :update :merge!
|
70
|
+
|
71
|
+
# Converts self to the hash
|
72
|
+
# @return [Hash]
|
73
|
+
def to_h
|
74
|
+
hash = {}
|
75
|
+
@table.each do |key, value|
|
76
|
+
hash[key] = value.is_a?(self.class) ? value.to_h : value
|
77
|
+
end
|
78
|
+
hash
|
79
|
+
end
|
80
|
+
|
81
|
+
# Return the contents of this instance as a string.
|
82
|
+
# @return [String]
|
83
|
+
def inspect
|
84
|
+
"#<#{self.class}"
|
85
|
+
.concat(@table.map { |k, v| " :#{k}=#{v.inspect}" }.join(" "))
|
86
|
+
.concat(">")
|
87
|
+
end
|
88
|
+
alias :to_s :inspect
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def method_missing(name, *args)
|
93
|
+
if @table[name.to_sym]
|
94
|
+
@table[name.to_sym]
|
95
|
+
else
|
96
|
+
if name[-1] == "="
|
97
|
+
@table[name[0..-2].to_sym] = args.first
|
98
|
+
else
|
99
|
+
@table[name.to_sym] = self.class.new
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require File.expand_path('../../lib/black_hole_struct', __FILE__)
|
2
|
+
require 'minitest/autorun'
|
3
|
+
|
4
|
+
class BlackHoleStructTest < Minitest::Test
|
5
|
+
def setup
|
6
|
+
@subject = BlackHoleStruct.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_instanciate_without_arguments
|
10
|
+
assert_instance_of BlackHoleStruct, @subject
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_accessor
|
14
|
+
@subject.theme = "white"
|
15
|
+
assert_equal @subject.theme, "white"
|
16
|
+
assert_equal @subject[:theme], "white"
|
17
|
+
|
18
|
+
@subject[:theme] = "black"
|
19
|
+
assert_equal @subject.theme, "black"
|
20
|
+
assert_equal @subject[:theme], "black"
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_missing_values
|
24
|
+
assert_instance_of BlackHoleStruct, @subject.missing
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_nested_accessor
|
28
|
+
@subject.dashboard.theme = "white"
|
29
|
+
assert_equal @subject.dashboard.theme, "white"
|
30
|
+
assert_equal @subject[:dashboard][:theme], "white"
|
31
|
+
|
32
|
+
@subject[:dashboards][:theme] = "black"
|
33
|
+
assert_equal @subject.dashboards.theme, "black"
|
34
|
+
assert_equal @subject[:dashboards][:theme], "black"
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_equality
|
38
|
+
@subject.dashboard.theme = "white"
|
39
|
+
other = BlackHoleStruct.new
|
40
|
+
other.dashboard.theme = "white"
|
41
|
+
assert_equal @subject, other
|
42
|
+
assert_equal @subject.eql?(other), true
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_instanciate_with_arguments
|
46
|
+
assert_raises ArgumentError do
|
47
|
+
BlackHoleStruct.new(Array.new)
|
48
|
+
end
|
49
|
+
|
50
|
+
subject = BlackHoleStruct.new(theme: "white")
|
51
|
+
assert_equal subject.theme, "white"
|
52
|
+
|
53
|
+
subject = BlackHoleStruct.new(dashboard: {theme: "white"})
|
54
|
+
assert_equal subject.dashboard.theme, "white"
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_delete_field
|
58
|
+
@subject.theme = "white"
|
59
|
+
@subject.delete_field(:theme)
|
60
|
+
assert_equal @subject.theme, BlackHoleStruct.new
|
61
|
+
|
62
|
+
@subject.dashboard.theme = "white"
|
63
|
+
@subject.delete_field(:dashboard)
|
64
|
+
assert_equal @subject.dashboard, BlackHoleStruct.new
|
65
|
+
assert_equal @subject.dashboard.theme, BlackHoleStruct.new
|
66
|
+
|
67
|
+
assert_equal @subject.delete_field(:missing), BlackHoleStruct.new
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_each_pair
|
71
|
+
assert_kind_of Enumerator, @subject.each_pair
|
72
|
+
|
73
|
+
@subject.theme = "white"
|
74
|
+
assert_equal @subject.each_pair.to_a, [[:theme, "white"]]
|
75
|
+
|
76
|
+
@subject.each_pair do |key, value|
|
77
|
+
assert_equal key, :theme
|
78
|
+
assert_equal value, "white"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_to_h
|
83
|
+
@subject.dashboard.theme = "white"
|
84
|
+
@subject.host = "127.0.0.1"
|
85
|
+
|
86
|
+
assert_equal @subject.to_h, {
|
87
|
+
dashboard: {theme: "white"},
|
88
|
+
host: "127.0.0.1"
|
89
|
+
}
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_merge
|
93
|
+
@subject.theme = "white"
|
94
|
+
@subject.merge!(size: 5)
|
95
|
+
|
96
|
+
assert_equal @subject.to_h, {
|
97
|
+
theme: "white", size: 5
|
98
|
+
}
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_inspect
|
102
|
+
assert_equal @subject.inspect, '#<BlackHoleStruct>'
|
103
|
+
@subject.theme = "white"
|
104
|
+
assert_equal @subject.inspect, '#<BlackHoleStruct :theme="white">'
|
105
|
+
end
|
106
|
+
end
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: black_hole_struct
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael Bensoussan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-01-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: minitest
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: yard
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: BlackHoleStruct is a data structure similar to an OpenStruct allowing
|
42
|
+
autovivification.
|
43
|
+
email:
|
44
|
+
- mbensoussan.is@gmail.com
|
45
|
+
executables: []
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- README.md
|
50
|
+
- lib/black_hole_struct.rb
|
51
|
+
- test/black_hole_struct_test.rb
|
52
|
+
homepage: https://github.com/mickey/black_hole_struct
|
53
|
+
licenses:
|
54
|
+
- MIT
|
55
|
+
metadata: {}
|
56
|
+
post_install_message:
|
57
|
+
rdoc_options: []
|
58
|
+
require_paths:
|
59
|
+
- lib
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
requirements: []
|
71
|
+
rubyforge_project:
|
72
|
+
rubygems_version: 2.5.1
|
73
|
+
signing_key:
|
74
|
+
specification_version: 4
|
75
|
+
summary: BlackHoleStruct is a data structure
|
76
|
+
test_files:
|
77
|
+
- test/black_hole_struct_test.rb
|