mimi-core 1.0.0 → 1.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 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