mimi-core 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4386bcac3a69eeb1f5a0422c445ba509e735ea4a
4
- data.tar.gz: 6c583235d2e0069d255c0598b3e2cce4f4631bcb
3
+ metadata.gz: db5931bbbdf22818f96d2979dac52cbc4d4058ed
4
+ data.tar.gz: d8b666e59ec1d340233f7b9a95ca7624dc06b22d
5
5
  SHA512:
6
- metadata.gz: d234685fd746173702527047e71aaa0c0d237da588e84b1de2f0fa23ecd74cca832569b91729af0e5968e53807d06d6eafb6077c73ac73d454cdfaa9ea041e92
7
- data.tar.gz: db3ece3e5d363f942ebd3d98ff92b2c286fc198f74261378dcee0d1b67e38d4dd3f88fbbb443e3f2c648623dc85c2eefd679f6fc59a94f16f65bd8cf4e35533a
6
+ metadata.gz: bbc4fe8b0d0150fc7181d050de3c037885f90a85c12a4fa55d6e00339151a7adf93506f44026533f91ab6a9f90132a79b72ae463bd5fbe696df8ae17c6a66aad
7
+ data.tar.gz: 0b5e725a4844406bf1cefbd98c1e7f3bee2a358195c4041dcb0f8cf4e00b5059905845d22ef08543e663725b84e045d643d648656c78fbb0ab0e46dda4eaf040
@@ -1,13 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'hashie'
4
-
5
3
  class Hash
6
4
  unless instance_methods(false).include?(:only)
5
+ #
6
+ # Returns a Hash with only given keys, if present
7
+ #
8
+ # @param *keys [*] list of keys
9
+ # @return [Hash] a new Hash
10
+ #
11
+ # @example
12
+ # h = { a: 1, b: 2, :c 3 }
13
+ # h.only(:a, :b, :d) # => { a: 1, b: 2 }
14
+ #
7
15
  def only(*keys)
8
16
  dup.only!(*keys)
9
17
  end
10
18
 
19
+ # Modifies the Hash keeping only given keys, if present
20
+ #
21
+ # @param *keys [*] list of keys
22
+ # @return [Hash] self
23
+ #
24
+ # @example
25
+ # h = { a: 1, b: 2, :c 3 }
26
+ # h.only!(:a, :b, :d)
27
+ # h # => { a: 1, b: 2 }
28
+ #
11
29
  def only!(*keys)
12
30
  if keys.size == 1 && keys.first.is_a?(Array)
13
31
  raise ArgumentError, 'Hash#only!() expects keys as list of arguments,' \
@@ -19,10 +37,30 @@ class Hash
19
37
  end
20
38
 
21
39
  unless instance_methods(false).include?(:except)
40
+ #
41
+ # Returns a Hash with given keys excluded, if present
42
+ #
43
+ # @param *keys [*] list of keys
44
+ # @return [Hash] a new Hash
45
+ #
46
+ # @example
47
+ # h = { a: 1, b: 2, :c 3 }
48
+ # h.except(:a, :b, :d) # => { c: 3 }
49
+ #
22
50
  def except(*keys)
23
51
  dup.except!(*keys)
24
52
  end
25
53
 
54
+ # Modifies the Hash excluding given keys, if present
55
+ #
56
+ # @param *keys [*] list of keys
57
+ # @return [Hash] self
58
+ #
59
+ # @example
60
+ # h = { a: 1, b: 2, :c 3 }
61
+ # h.except!(:a, :b, :d)
62
+ # h # => { c: 3 }
63
+ #
26
64
  def except!(*keys)
27
65
  if keys.size == 1 && keys.first.is_a?(Array)
28
66
  raise ArgumentError, 'Hash#except!() expects keys as list of arguments,' \
@@ -34,10 +72,51 @@ class Hash
34
72
  end
35
73
 
36
74
  unless instance_methods(false).include?(:deep_merge)
37
- include Hashie::Extensions::DeepMerge
75
+ #
76
+ # Deep merges self (left) Hash with another Hash
77
+ #
78
+ # On keys existing in both Hashes:
79
+ # * merges Hash values by merging left Hash with the right Hash
80
+ # * merges Array values by union operator
81
+ # * for other values overwrites left Hash value with the right Hash value
82
+ #
83
+ # @param right [Hash] the right (other) Hash
84
+ # @return [Hash] self
85
+ #
86
+ def deep_merge!(right)
87
+ right.each do |k ,v|
88
+ unless self.key?(k)
89
+ self[k] = v
90
+ next
91
+ end
92
+ if self[k].is_a?(Hash) && v.is_a?(Hash)
93
+ self[k].deep_merge!(v)
94
+ elsif self[k].is_a?(Array) && v.is_a?(Array)
95
+ self[k] = self[k] | v
96
+ else
97
+ # unmergeable values, overwrite
98
+ self[k] = v
99
+ end
100
+ end
101
+ self
102
+ end
103
+
104
+ # @see #deep_merge!
105
+ #
106
+ # @param right [Hash] the right (other) Hash
107
+ # @return [Hash] a new Hash
108
+ #
109
+ def deep_merge(right)
110
+ deep_dup.deep_merge!(right)
111
+ end
38
112
  end
39
113
 
40
114
  unless instance_methods(false).include?(:deep_dup)
115
+ #
116
+ # Duplicates a Hash with all nested values
117
+ #
118
+ # @return [Hash] a new Hash
119
+ #
41
120
  def deep_dup
42
121
  map do |k, v|
43
122
  v = v.respond_to?(:deep_dup) ? v.deep_dup : v.dup
@@ -47,6 +126,11 @@ class Hash
47
126
  end
48
127
 
49
128
  unless instance_methods(false).include?(:symbolize_keys)
129
+ #
130
+ # Symbolizes Hash keys
131
+ #
132
+ # @return [Hash] a new Hash
133
+ #
50
134
  def symbolize_keys
51
135
  map do |k, v|
52
136
  k = k.respond_to?(:to_sym) ? k.to_sym : k
@@ -54,12 +138,21 @@ class Hash
54
138
  end.to_h
55
139
  end
56
140
 
141
+ # Modifies the Hash symbolizing its keys
142
+ #
143
+ # @return [Hash] self
144
+ #
57
145
  def symbolize_keys!
58
146
  replace(symbolize_keys)
59
147
  end
60
148
  end
61
149
 
62
150
  unless instance_methods(false).include?(:deep_symbolize_keys)
151
+ #
152
+ # Symbolizes Hash keys including all nested Hashes
153
+ #
154
+ # @return [Hash] a new Hash
155
+ #
63
156
  def deep_symbolize_keys
64
157
  map do |k, v|
65
158
  k = k.respond_to?(:to_sym) ? k.to_sym : k
@@ -68,12 +161,21 @@ class Hash
68
161
  end.to_h
69
162
  end
70
163
 
164
+ # Modifies the Hash symbolizing its keys including all nested Hashes
165
+ #
166
+ # @return [Hash] self
167
+ #
71
168
  def deep_symbolize_keys!
72
169
  replace(deep_symbolize_keys)
73
170
  end
74
171
  end
75
172
 
76
173
  unless instance_methods(false).include?(:stringify_keys)
174
+ #
175
+ # Stringifies Hash keys
176
+ #
177
+ # @return [Hash] a new Hash
178
+ #
77
179
  def stringify_keys
78
180
  map do |k, v|
79
181
  k = k.respond_to?(:to_s) ? k.to_s : k
@@ -81,12 +183,21 @@ class Hash
81
183
  end.to_h
82
184
  end
83
185
 
186
+ # Modifies the Hash stringifying its keys
187
+ #
188
+ # @return [Hash] self
189
+ #
84
190
  def stringify_keys!
85
191
  replace(stringify_keys)
86
192
  end
87
193
  end
88
194
 
89
195
  unless instance_methods(false).include?(:deep_stringify_keys)
196
+ #
197
+ # Stringifies Hash keys including all nested Hashes
198
+ #
199
+ # @return [Hash] a new Hash
200
+ #
90
201
  def deep_stringify_keys
91
202
  map do |k, v|
92
203
  k = k.respond_to?(:to_s) ? k.to_s : k
@@ -95,6 +206,10 @@ class Hash
95
206
  end.to_h
96
207
  end
97
208
 
209
+ # Modifies the Hash stringifying its keys including all nested Hashes
210
+ #
211
+ # @return [Hash] self
212
+ #
98
213
  def deep_stringify_keys!
99
214
  replace(deep_stringify_keys)
100
215
  end
@@ -103,25 +218,65 @@ end
103
218
 
104
219
  class Array
105
220
  unless instance_methods(false).include?(:only)
106
- def only(*keys)
107
- dup.only!(*keys)
221
+ #
222
+ # Returns an Array with only selected values, if present
223
+ #
224
+ # @param *values [*] list of values
225
+ # @return [Array] a new Array
226
+ #
227
+ # @example
228
+ # a = [:a, :b, :c]
229
+ # a.only(:a, :b, :d) # => [:a, :b]
230
+ #
231
+ def only(*values)
232
+ dup.only!(*values)
108
233
  end
109
234
 
110
- def only!(*keys)
111
- if keys.size == 1 && keys.first.is_a?(Array)
112
- raise ArgumentError, 'Array#only!() expects keys as list of arguments,' \
235
+ # Modifies the Array keeping only given values, if present
236
+ #
237
+ # @param *values [*] list of values
238
+ # @return [Array] self
239
+ #
240
+ # @example
241
+ # a = [:a, :b, :c]
242
+ # a.only!(:a, :b, :d)
243
+ # a # => [:a, :b]
244
+ #
245
+ def only!(*values)
246
+ if values.size == 1 && values.first.is_a?(Array)
247
+ raise ArgumentError, 'Array#only!() expects values as list of arguments,' \
113
248
  ' not an Array as first argument'
114
249
  end
115
- select! { |k| keys.include?(k) }
250
+ select! { |k| values.include?(k) }
116
251
  self
117
252
  end
118
253
  end
119
254
 
120
255
  unless instance_methods(false).include?(:except)
256
+ #
257
+ # Returns an Array with given values excluded, if present
258
+ #
259
+ # @param *values [*] list of values
260
+ # @return [Array] a new Array
261
+ #
262
+ # @example
263
+ # a = [:a, :b, :c]
264
+ # a.except(:a, :b, :d) # => [:c]
265
+ #
121
266
  def except(*keys)
122
267
  dup.except!(*keys)
123
268
  end
124
269
 
270
+ # Modifies the Array excluding given values, if present
271
+ #
272
+ # @param *values [*] list of values
273
+ # @return [Array] self
274
+ #
275
+ # @example
276
+ # a = [:a, :b, :c]
277
+ # a.except!(:a, :b, :d)
278
+ # a # => [:c]
279
+ #
125
280
  def except!(*keys)
126
281
  if keys.size == 1 && keys.first.is_a?(Array)
127
282
  raise ArgumentError, 'Array#except!() expects keys as list of arguments,' \
@@ -133,6 +288,11 @@ class Array
133
288
  end
134
289
 
135
290
  unless instance_methods(false).include?(:deep_dup)
291
+ #
292
+ # Duplicates an Array with all nested values
293
+ #
294
+ # @return [Hash] a new Hash
295
+ #
136
296
  def deep_dup
137
297
  map do |v|
138
298
  v.respond_to?(:deep_dup) ? v.deep_dup : v.dup
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mimi
4
+ module Core
5
+ #
6
+ # Mimi::Core::Struct is a simple immutable data structure.
7
+ #
8
+ # It allows instantiating an object from a set of attributes and makes them
9
+ # available as object methods and Hash paramaters:
10
+ # my_object = Mimi::Core::Struct.new(a: 1, b: 2)
11
+ #
12
+ # my_object.a # => 1
13
+ # my_object[:a] # => 1
14
+ # my_object['a'] # => 1
15
+ #
16
+ # It only allows access to defined attributes:
17
+ # my_object.c # => NoMethodError
18
+ # my_object[:c] # => NameError
19
+ #
20
+ class Struct
21
+ #
22
+ # Creates a Struct object from a set of attributes
23
+ #
24
+ # @param attrs [Hash]
25
+ #
26
+ def initialize(attrs = {})
27
+ raise ArgumentError, "Hash is expected as attrs" unless attrs.is_a?(Hash)
28
+ @attributes = attrs.map { |k, v| [k.to_sym, v.dup] }.to_h
29
+ @attributes.keys.each do |attr_name|
30
+ define_singleton_method(attr_name) { self[attr_name] }
31
+ end
32
+ end
33
+
34
+ # Fetches attribute by its name
35
+ #
36
+ # @param name [String,Symbol]
37
+ # @return [Object] attribute's value
38
+ #
39
+ def [](attr_name)
40
+ attr_name = attr_name.to_sym
41
+ unless @attributes.key?(attr_name)
42
+ raise NameError, "undefined attribute #{attr_name.inspect}"
43
+ end
44
+ @attributes[attr_name]
45
+ end
46
+
47
+ # Returns Struct attributes as a Hash
48
+ #
49
+ # @return [Hash]
50
+ #
51
+ def to_h
52
+ @attributes
53
+ end
54
+ end # class Struct
55
+ end # module Core
56
+ end # module Mimi
@@ -1,5 +1,5 @@
1
1
  module Mimi
2
2
  module Core
3
- VERSION = '1.0.0'.freeze
3
+ VERSION = '1.1.0'.freeze
4
4
  end
5
5
  end
data/lib/mimi/core.rb CHANGED
@@ -113,3 +113,5 @@ require_relative 'core/core_ext'
113
113
  require_relative 'core/inheritable_property'
114
114
  require_relative 'core/module'
115
115
  require_relative 'core/manifest'
116
+ require_relative 'core/struct'
117
+
data/mimi-core.gemspec CHANGED
@@ -27,8 +27,6 @@ Gem::Specification.new do |spec|
27
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ['lib']
29
29
 
30
- spec.add_dependency 'hashie', '~> 3.6'
31
-
32
30
  spec.add_development_dependency 'bundler', '~> 1.11'
33
31
  spec.add_development_dependency 'pry', '~> 0.10'
34
32
  spec.add_development_dependency 'rake', '~> 10.0'
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mimi-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Kukushkin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-05-16 00:00:00.000000000 Z
11
+ date: 2019-06-28 00:00:00.000000000 Z
12
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: '3.6'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '3.6'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: bundler
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -104,6 +90,7 @@ files:
104
90
  - lib/mimi/core/manifest.rb
105
91
  - lib/mimi/core/module.rb
106
92
  - lib/mimi/core/rake.rb
93
+ - lib/mimi/core/struct.rb
107
94
  - lib/mimi/core/version.rb
108
95
  - mimi-core.gemspec
109
96
  homepage: https://github.com/kukushkin/mimi-core