clean-hash 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8455736b6df4f0682b955aa5aa0d70a313b60a4ca01a51029e55e78d4d52b4bf
4
+ data.tar.gz: 426946203c65e097eaefcf354e6af8bb19c59e1dc424384f5831e6420ae41bb3
5
+ SHA512:
6
+ metadata.gz: d50a1d7af39b6e0980c7141c3ad5ae1e9c76db707b2b0a2e8191a3062f16169a305aab6e8710ca61c0504b388a893ebc66de3ac4edc19b8801f79068bfa463af
7
+ data.tar.gz: bbced94df41e9ddfd18b5b8781d8c23c77530f4d5e3951215f86860eb99bc605da77971d72576b4edd157d0f013e72eda345fc937270e60206a40e39a201ceba
@@ -0,0 +1 @@
1
+ 0.3.0
@@ -0,0 +1,7 @@
1
+ require 'hashie'
2
+
3
+ require_relative 'clean-hash/base'
4
+ require_relative 'clean-hash/deep_merge'
5
+ require_relative 'clean-hash/mutex_hash'
6
+ require_relative 'clean-hash/hash_pollute'
7
+
@@ -0,0 +1,105 @@
1
+ class CleanHash
2
+ def initialize data, mode=nil
3
+ @data = data
4
+ @mode = mode
5
+
6
+ case mode
7
+ when :safe
8
+ @is_safe = true
9
+ else
10
+ @is_strict = true if mode
11
+ end
12
+ end
13
+
14
+ # for debug
15
+ def to_json
16
+ JSON.pretty_generate @data
17
+ end
18
+
19
+ # for puts
20
+ def to_ary
21
+ [@data]
22
+ end
23
+
24
+ def [] key
25
+ __value_for key.to_s
26
+ end
27
+
28
+ def []= key, value
29
+ __error_set
30
+ end
31
+
32
+ def key? name
33
+ __value_for name
34
+ true
35
+ rescue NoMethodError
36
+ false
37
+ end
38
+
39
+ def keys
40
+ @data.keys
41
+ end
42
+
43
+ def values
44
+ @data.values
45
+ end
46
+
47
+ def to_h
48
+ @data
49
+ end
50
+
51
+ def method_missing name, *args
52
+ m = name.to_s
53
+
54
+ if m.end_with?('=')
55
+ m = m.sub('=', '')
56
+
57
+ __error_set if @is_strict && !key?(m)
58
+
59
+ value = args.first
60
+
61
+ if @is_safe
62
+ value = value.to_s if value.is_a?(Symbol)
63
+
64
+ unless value.nil? || value.is_a?(Hash) || value.is_a?(Numeric) || value.is_a?(String)
65
+ raise ArgumentError.new('Unsupported safe type: %s' % value.class)
66
+ end
67
+ end
68
+
69
+ m = m.to_sym if @data[m].nil?
70
+
71
+ @data[m] = value
72
+ elsif m.end_with?('?')
73
+ begin
74
+ !__value_for(m.sub('?', '')).nil?
75
+ rescue NoMethodError
76
+ false
77
+ end
78
+ else
79
+ __value_for m
80
+ end
81
+ end
82
+
83
+ private
84
+
85
+ def __value_for name
86
+ data = @data[name.to_s]
87
+ data = @data[name.to_sym] if data.nil?
88
+
89
+ if data.nil?
90
+ if @is_strict && !keys.include?(name.to_sym)
91
+ raise NoMethodError, 'Clean hash: key "%s" not found' % name
92
+ else
93
+ nil
94
+ end
95
+ elsif data.is_a?(Hash)
96
+ CleanHash.new data, @mode
97
+ else
98
+ data
99
+ end
100
+ end
101
+
102
+ def __error_set
103
+ raise NoMethodError, 'Clean hash: setting a key value is not allowedß'
104
+ end
105
+ end
@@ -0,0 +1,5 @@
1
+ class CleanHash
2
+ class DeepMerge < Hash
3
+ include ::Hashie::Extensions::DeepMerge
4
+ end
5
+ end
@@ -0,0 +1,47 @@
1
+ class CleanHash
2
+ def self.pollute!
3
+ ::Hash.class_eval do
4
+ # merge but to not overwrite keys
5
+ def deep_merge hash
6
+ klass = ::CleanHash::DeepMerge
7
+ klass[deep_clone].deep_merge klass[hash]
8
+ end
9
+
10
+ # true clone of the hash with 0 references to the old one
11
+ def deep_clone
12
+ Marshal.load(Marshal.dump(self))
13
+ end
14
+
15
+ def to_ch mode=nil
16
+ if mode.is_a?(Array)
17
+ for key in keys
18
+ raise ArgumentError, 'CleanHash key "%s" not allowed' % key unless mode.include?(key)
19
+ end
20
+
21
+ for key in mode
22
+ self[key] = nil unless key?(key)
23
+ end
24
+
25
+ ::CleanHash.new self, :strict
26
+ else
27
+ supported = %i{safe mutex strict}
28
+ raise ArgumentError, 'Unsupported type "%s", supported: %s' % [mode, supported] if mode && !supported.include?(mode)
29
+
30
+ if mode == :mutex
31
+ ::CleanHash::MutexHash.new self
32
+ else
33
+ ::CleanHash.new self, mode
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ ::Array.class_eval do
40
+ # coverts keys to empty hash methods and returns read_only hash
41
+ def to_ch strict=false
42
+ hash = inject({}) { |h, key| h[key] = nil; h }
43
+ ::CleanHash.new hash, :strict
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,20 @@
1
+ # Thread safe hash
2
+ class CleanHash
3
+ class MutexHash
4
+ MUTEX = Mutex.new
5
+
6
+ def initialize name=nil
7
+ @data ||= {}
8
+ end
9
+
10
+ def [] name
11
+ @data[name.to_sym]
12
+ end
13
+
14
+ def []= name, value
15
+ MUTEX.synchronize do
16
+ @data[name.to_sym] = value
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,3 @@
1
+ require_relative '../clean-hash'
2
+
3
+ CleanHash.pollute!
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: clean-hash
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Dino Reic
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-02-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: hashie
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4'
27
+ description: Gem provides simple access to common Ruby hash types
28
+ email: reic.dino@gmail.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - "./.version"
34
+ - "./lib/clean-hash.rb"
35
+ - "./lib/clean-hash/base.rb"
36
+ - "./lib/clean-hash/deep_merge.rb"
37
+ - "./lib/clean-hash/hash_pollute.rb"
38
+ - "./lib/clean-hash/mutex_hash.rb"
39
+ - "./lib/clean-hash/pollute.rb"
40
+ homepage: https://github.com/dux/clean-hash
41
+ licenses:
42
+ - MIT
43
+ metadata: {}
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ requirements: []
59
+ rubygems_version: 3.0.6
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: Hash with indifferent access, mash, strict config mode, deep copy
63
+ test_files: []