ribbon 0.7.0 → 0.8.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.
- data/lib/ribbon.rb +156 -213
- data/lib/ribbon/core_extensions.rb +9 -4
- data/lib/ribbon/core_extensions/array.rb +14 -21
- data/lib/ribbon/core_extensions/basic_object.rb +9 -5
- data/lib/ribbon/core_extensions/hash.rb +9 -16
- data/lib/ribbon/core_extensions/object.rb +7 -4
- data/lib/ribbon/core_extensions/object/option_scope.rb +1 -1
- data/lib/ribbon/core_extensions/object/yield_or_eval.rb +1 -1
- data/lib/ribbon/gem.rb +1 -1
- data/lib/ribbon/options.rb +10 -7
- data/lib/ribbon/raw.rb +195 -0
- data/ribbon.version +1 -1
- metadata +5 -5
- data/lib/ribbon/wrapper.rb +0 -224
data/lib/ribbon.rb
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
%w(
|
|
2
2
|
|
|
3
|
-
ribbon/core_extensions/basic_object
|
|
4
3
|
ribbon/gem
|
|
5
4
|
ribbon/options
|
|
6
|
-
ribbon/
|
|
5
|
+
ribbon/raw
|
|
7
6
|
|
|
8
7
|
).each { |file| require file }
|
|
9
8
|
|
|
@@ -56,142 +55,127 @@ ribbon/wrapper
|
|
|
56
55
|
#
|
|
57
56
|
# @author Matheus Afonso Martins Moreira
|
|
58
57
|
# @since 0.1.0
|
|
59
|
-
# @see Ribbon::
|
|
60
|
-
class Ribbon
|
|
58
|
+
# @see Ribbon::Raw
|
|
59
|
+
class Ribbon
|
|
61
60
|
|
|
62
|
-
# The
|
|
61
|
+
# The raw ribbon.
|
|
63
62
|
#
|
|
64
|
-
# @return [
|
|
65
|
-
# @
|
|
66
|
-
def
|
|
67
|
-
@
|
|
63
|
+
# @return [Ribbon::Raw] this ribbon's raw ribbon
|
|
64
|
+
# @since 0.8.0
|
|
65
|
+
def raw
|
|
66
|
+
@raw ||= Ribbon::Raw.new
|
|
68
67
|
end
|
|
69
68
|
|
|
70
|
-
#
|
|
69
|
+
# Sets this ribbon's raw ribbon.
|
|
70
|
+
#
|
|
71
|
+
# @param [Ribbon, Ribbon::Raw, #to_hash] object the hash-like object
|
|
72
|
+
# @return [Ribbon::Raw] the raw ribbon
|
|
73
|
+
# @since 0.8.0
|
|
74
|
+
def raw=(object)
|
|
75
|
+
@raw = Ribbon.extract_raw_from object
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Initializes a new ribbon with the given values.
|
|
71
79
|
#
|
|
72
80
|
# If given a block, the ribbon will be yielded to it. If the block doesn't
|
|
73
81
|
# take any arguments, it will be evaluated in the context of the ribbon.
|
|
74
82
|
#
|
|
75
|
-
#
|
|
76
|
-
#
|
|
77
|
-
# @
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
# @see convert_all!
|
|
81
|
-
def initialize(hash = {}, &block)
|
|
82
|
-
__hash__.merge! ::Ribbon.extract_hash_from(hash)
|
|
83
|
+
# @param [Ribbon, Ribbon::Raw, #to_hash] initial_values the initial values
|
|
84
|
+
# @see #raw=
|
|
85
|
+
# @see Ribbon::Raw#initialize
|
|
86
|
+
def initialize(initial_values = Ribbon::Raw.new, &block)
|
|
87
|
+
self.raw = initial_values
|
|
83
88
|
__yield_or_eval__ &block
|
|
84
|
-
::Ribbon.convert_all! self
|
|
85
89
|
end
|
|
86
90
|
|
|
87
|
-
#
|
|
88
|
-
#
|
|
89
|
-
# If given a block, the value will be yielded to it. If the block doesn't take
|
|
90
|
-
# any arguments, it will be evaluated in the context of the value.
|
|
91
|
+
# The hash used by the raw ribbon.
|
|
91
92
|
#
|
|
92
|
-
# @
|
|
93
|
-
# @
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
value = ::Ribbon.convert __hash__[key]
|
|
97
|
-
value.__yield_or_eval__ &block
|
|
98
|
-
self[key] = value
|
|
93
|
+
# @return [Hash] the internal hash of the raw ribbon
|
|
94
|
+
# @since 0.8.0
|
|
95
|
+
def internal_hash
|
|
96
|
+
raw.__hash__
|
|
99
97
|
end
|
|
100
98
|
|
|
101
|
-
#
|
|
102
|
-
#
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
# ribbon = Ribbon.new
|
|
107
|
-
#
|
|
108
|
-
# ribbon[:key] = :value
|
|
109
|
-
# ribbon[:key]
|
|
110
|
-
# # => :value
|
|
111
|
-
#
|
|
112
|
-
# ribbon[:key] = :multiple, :values
|
|
113
|
-
# ribbon[:key]
|
|
114
|
-
# # => [:multiple, :values]
|
|
115
|
-
def []=(key, *values)
|
|
116
|
-
__hash__[key] = if values.size == 1 then values.first else values end
|
|
99
|
+
# Forwards the method, arguments and block to the raw ribbon's hash, if it
|
|
100
|
+
# responds to the method, or to the raw ribbon itself otherwise.
|
|
101
|
+
def method_missing(method, *arguments, &block)
|
|
102
|
+
if (hash = internal_hash).respond_to? method then hash
|
|
103
|
+
else raw end.__send__ method, *arguments, &block
|
|
117
104
|
end
|
|
118
105
|
|
|
119
|
-
#
|
|
106
|
+
# Merges everything inside this ribbon with everything inside the given
|
|
107
|
+
# ribbon, creating a new instance in the process.
|
|
120
108
|
#
|
|
121
|
-
#
|
|
122
|
-
#
|
|
123
|
-
#
|
|
124
|
-
#
|
|
125
|
-
#
|
|
109
|
+
# @param [Ribbon, Ribbon::Raw, #to_hash] ribbon the ribbon with new values
|
|
110
|
+
# @return [Ribbon] a new ribbon containing the results of the deep merge
|
|
111
|
+
# @yieldparam key the key which identifies both values
|
|
112
|
+
# @yieldparam old_value the value from this ribbon
|
|
113
|
+
# @yieldparam new_value the value from the given ribbon
|
|
114
|
+
# @yieldreturn the object that will be used as the new value
|
|
115
|
+
# @since 0.8.0
|
|
116
|
+
# @see #deep_merge!
|
|
117
|
+
# @see deep_merge
|
|
118
|
+
def deep_merge(ribbon, &block)
|
|
119
|
+
Ribbon.new Ribbon.deep_merge(self, ribbon, &block)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Merges everything inside this ribbon with the given ribbon in place.
|
|
126
123
|
#
|
|
127
|
-
#
|
|
124
|
+
# @param [Ribbon, Ribbon::Raw, #to_hash] ribbon the ribbon with new values
|
|
125
|
+
# @return [self] this ribbon
|
|
126
|
+
# @yieldparam key the key which identifies both values
|
|
127
|
+
# @yieldparam old_value the value from this ribbon
|
|
128
|
+
# @yieldparam new_value the value from the given ribbon
|
|
129
|
+
# @yieldreturn the object that will be used as the new value
|
|
130
|
+
# @since 0.8.0
|
|
131
|
+
# @see #deep_merge
|
|
132
|
+
# @see deep_merge!
|
|
133
|
+
def deep_merge!(ribbon, &block)
|
|
134
|
+
Ribbon.deep_merge! self, ribbon, &block
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Converts this ribbon and all ribbons inside into hashes.
|
|
128
138
|
#
|
|
129
|
-
#
|
|
130
|
-
#
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
#
|
|
139
|
+
# @return [Hash] the converted contents of this wrapped ribbon
|
|
140
|
+
# @since 0.8.0
|
|
141
|
+
def to_hash
|
|
142
|
+
to_hash_recursive
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Converts this ribbon to a hash and serializes it with YAML.
|
|
136
146
|
#
|
|
137
|
-
#
|
|
138
|
-
#
|
|
139
|
-
#
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
method_string = method.to_s
|
|
143
|
-
key = method_string.strip.gsub(/[=?!]$/, '').strip.intern
|
|
144
|
-
case method_string[-1]
|
|
145
|
-
when ?=
|
|
146
|
-
__send__ :[]=, key, *args
|
|
147
|
-
when ?!
|
|
148
|
-
__send__ :[]=, key, *args unless args.empty?
|
|
149
|
-
self[key, &block]
|
|
150
|
-
self
|
|
151
|
-
when ??
|
|
152
|
-
begin self.__hash__.fetch key, *args, &block
|
|
153
|
-
rescue ::KeyError; nil end
|
|
154
|
-
else
|
|
155
|
-
__send__ :[]=, key, *args unless args.empty?
|
|
156
|
-
self[key, &block]
|
|
157
|
-
end
|
|
147
|
+
# @return [String] the YAML string that represents this ribbon
|
|
148
|
+
# @since 0.8.0
|
|
149
|
+
# @see from_yaml
|
|
150
|
+
def to_yaml
|
|
151
|
+
to_hash.to_yaml
|
|
158
152
|
end
|
|
159
153
|
|
|
160
|
-
#
|
|
154
|
+
# Delegates to the raw ribbon.
|
|
161
155
|
#
|
|
162
|
-
# @option opts [String] :separator Separates the key/value pair.
|
|
163
|
-
# Default is <tt>': '</tt>.
|
|
164
|
-
# @option opts [Symbol] :key Will be sent to the key in order to convert
|
|
165
|
-
# it to a string. Default is <tt>:to_s</tt>.
|
|
166
|
-
# @option opts [Symbol] :value Will be sent to the value in order to
|
|
167
|
-
# convert it to a string. Default is
|
|
168
|
-
# <tt>:inspect</tt>.
|
|
169
156
|
# @return [String] the string representation of this ribbon
|
|
170
|
-
|
|
171
|
-
|
|
157
|
+
# @see Ribbon::Raw#to_s
|
|
158
|
+
def to_s(*arguments, &block)
|
|
159
|
+
raw.to_s *arguments, &block
|
|
172
160
|
end
|
|
173
161
|
|
|
174
162
|
alias inspect to_s
|
|
175
163
|
|
|
176
164
|
private
|
|
177
165
|
|
|
178
|
-
#
|
|
179
|
-
# inside it, using the given options.
|
|
166
|
+
# Converts this ribbon and all ribbons inside into hashes using recursion.
|
|
180
167
|
#
|
|
181
|
-
# @
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
"#{k}#{separator}#{v}"
|
|
193
|
-
end.join ', '
|
|
194
|
-
"{#{values}}"
|
|
168
|
+
# @return [Hash] the converted contents of this ribbon
|
|
169
|
+
def to_hash_recursive(raw_ribbon = self.raw)
|
|
170
|
+
{}.tap do |hash|
|
|
171
|
+
raw_ribbon.__hash__.each do |key, value|
|
|
172
|
+
hash[key] = case value
|
|
173
|
+
when Ribbon then to_hash_recursive value.raw
|
|
174
|
+
when Ribbon::Raw then to_hash_recursive value
|
|
175
|
+
else value
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
195
179
|
end
|
|
196
180
|
|
|
197
181
|
end
|
|
@@ -200,57 +184,70 @@ class << Ribbon
|
|
|
200
184
|
|
|
201
185
|
alias [] new
|
|
202
186
|
|
|
203
|
-
#
|
|
187
|
+
# Whether the given object is a {Ribbon::Raw raw ribbon}.
|
|
204
188
|
#
|
|
205
|
-
# @
|
|
206
|
-
# @
|
|
207
|
-
|
|
208
|
-
|
|
189
|
+
# @param object the object to be tested
|
|
190
|
+
# @return [true, false] whether the object is a raw ribbon
|
|
191
|
+
# @since 0.8.0
|
|
192
|
+
def raw?(object)
|
|
193
|
+
Ribbon::Raw === object
|
|
209
194
|
end
|
|
210
195
|
|
|
211
|
-
#
|
|
196
|
+
# Whether the object is compatible with methods that take hashes or ribbons as
|
|
197
|
+
# arguments.
|
|
212
198
|
#
|
|
213
|
-
# @param object the object to
|
|
214
|
-
# @return the
|
|
215
|
-
# @since 0.
|
|
216
|
-
def
|
|
199
|
+
# @param object the object to be tested
|
|
200
|
+
# @return [true, false] whether the object is a raw ribbon
|
|
201
|
+
# @since 0.8.0
|
|
202
|
+
def compatible?(object)
|
|
203
|
+
[Ribbon, Ribbon::Raw, Hash].any? { |type| type === object }
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Extracts the hash of a ribbon. Will attempt to convert other objects.
|
|
207
|
+
#
|
|
208
|
+
# @param [Ribbon, Ribbon::Raw, #to_hash] object the object to convert
|
|
209
|
+
# @return [Hash] the resulting hash
|
|
210
|
+
# @since 0.2.1
|
|
211
|
+
def extract_hash_from(object)
|
|
217
212
|
case object
|
|
218
|
-
when
|
|
219
|
-
|
|
220
|
-
else object
|
|
213
|
+
when Ribbon, Ribbon::Raw then object.__hash__
|
|
214
|
+
else object.to_hash
|
|
221
215
|
end
|
|
222
216
|
end
|
|
223
217
|
|
|
224
|
-
#
|
|
218
|
+
# Extracts a raw ribbon from the given object.
|
|
225
219
|
#
|
|
226
|
-
# @param [Ribbon, Ribbon::
|
|
227
|
-
#
|
|
228
|
-
# @
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
when Ribbon then convert_all! value
|
|
235
|
-
when Ribbon::Wrapper then convert_all! value.ribbon
|
|
236
|
-
else convert value
|
|
237
|
-
end
|
|
220
|
+
# @param [Ribbon, Ribbon::Raw, #to_hash] object the hash-like object
|
|
221
|
+
# @return [Ribbon::Raw] the raw ribbon
|
|
222
|
+
# @since 0.8.0
|
|
223
|
+
def extract_raw_from(object)
|
|
224
|
+
case object
|
|
225
|
+
when Ribbon then object.raw
|
|
226
|
+
when Ribbon::Raw then object
|
|
227
|
+
else Ribbon::Raw.new object.to_hash
|
|
238
228
|
end
|
|
239
|
-
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# Deserializes the hash from the string using YAML and uses it to construct a
|
|
232
|
+
# new ribbon.
|
|
233
|
+
#
|
|
234
|
+
# @param [String] string a valid YAML string
|
|
235
|
+
# @return [Ribbon] a new Ribbon
|
|
236
|
+
# @since 0.4.7
|
|
237
|
+
def from_yaml(string)
|
|
238
|
+
Ribbon.new YAML.load(string)
|
|
240
239
|
end
|
|
241
240
|
|
|
242
241
|
# Merges the hashes of the given ribbons.
|
|
243
242
|
#
|
|
244
|
-
# @param [Ribbon, Ribbon::
|
|
245
|
-
#
|
|
246
|
-
# @param [Ribbon, Ribbon::Wrapper, #to_hash] new_ribbon the ribbon with new
|
|
247
|
-
# values
|
|
243
|
+
# @param [Ribbon, Ribbon::Raw, #to_hash] old_ribbon the ribbon with old values
|
|
244
|
+
# @param [Ribbon, Ribbon::Raw, #to_hash] new_ribbon the ribbon with new values
|
|
248
245
|
# @return [Ribbon] a new ribbon containing the results of the merge
|
|
249
246
|
# @yieldparam key the key which identifies both values
|
|
250
247
|
# @yieldparam old_value the value from old_ribbon
|
|
251
248
|
# @yieldparam new_value the value from new_ribbon
|
|
252
249
|
# @yieldreturn the object that will be used as the new value
|
|
253
|
-
# @since 0.
|
|
250
|
+
# @since 0.8.0
|
|
254
251
|
# @see merge!
|
|
255
252
|
# @see extract_hash_from
|
|
256
253
|
def merge(old_ribbon, new_ribbon, &block)
|
|
@@ -262,17 +259,15 @@ class << Ribbon
|
|
|
262
259
|
|
|
263
260
|
# Merges the hashes of the given ribbons in place.
|
|
264
261
|
#
|
|
265
|
-
# @param [Ribbon, Ribbon::
|
|
266
|
-
#
|
|
267
|
-
# @
|
|
268
|
-
#
|
|
269
|
-
# @return [Ribbon, Ribbon::Wrapper, Hash] old_ribbon, which will contain the
|
|
270
|
-
# results of the merge
|
|
262
|
+
# @param [Ribbon, Ribbon::Raw, #to_hash] old_ribbon the ribbon with old values
|
|
263
|
+
# @param [Ribbon, Ribbon::Raw, #to_hash] new_ribbon the ribbon with new values
|
|
264
|
+
# @return [Ribbon, Ribbon::Raw, Hash] old_ribbon, which will contain the
|
|
265
|
+
# results of the merge
|
|
271
266
|
# @yieldparam key the key which identifies both values
|
|
272
267
|
# @yieldparam old_value the value from old_ribbon
|
|
273
268
|
# @yieldparam new_value the value from new_ribbon
|
|
274
269
|
# @yieldreturn the object that will be used as the new value
|
|
275
|
-
# @since 0.
|
|
270
|
+
# @since 0.8.0
|
|
276
271
|
# @see merge
|
|
277
272
|
# @see extract_hash_from
|
|
278
273
|
def merge!(old_ribbon, new_ribbon, &block)
|
|
@@ -284,16 +279,14 @@ class << Ribbon
|
|
|
284
279
|
|
|
285
280
|
# Merges everything inside the given ribbons.
|
|
286
281
|
#
|
|
287
|
-
# @param [Ribbon, Ribbon::
|
|
288
|
-
#
|
|
289
|
-
# @param [Ribbon, Ribbon::Wrapper, #to_hash] new_ribbon the ribbon with new
|
|
290
|
-
# values
|
|
282
|
+
# @param [Ribbon, Ribbon::Raw, #to_hash] old_ribbon the ribbon with old values
|
|
283
|
+
# @param [Ribbon, Ribbon::Raw, #to_hash] new_ribbon the ribbon with new values
|
|
291
284
|
# @return [Ribbon] a new ribbon containing the results of the merge
|
|
292
285
|
# @yieldparam key the key which identifies both values
|
|
293
286
|
# @yieldparam old_value the value from old_ribbon
|
|
294
287
|
# @yieldparam new_value the value from new_ribbon
|
|
295
288
|
# @yieldreturn the object that will be used as the new value
|
|
296
|
-
# @since 0.
|
|
289
|
+
# @since 0.8.0
|
|
297
290
|
# @see merge
|
|
298
291
|
# @see deep_merge!
|
|
299
292
|
# @see extract_hash_from
|
|
@@ -303,17 +296,15 @@ class << Ribbon
|
|
|
303
296
|
|
|
304
297
|
# Merges everything inside the given ribbons in place.
|
|
305
298
|
#
|
|
306
|
-
# @param [Ribbon, Ribbon::
|
|
307
|
-
#
|
|
308
|
-
# @
|
|
309
|
-
#
|
|
310
|
-
# @return [Ribbon, Ribbon::Wrapper, Hash] old_ribbon, which will contain the
|
|
311
|
-
# results of the merge
|
|
299
|
+
# @param [Ribbon, Ribbon::Raw, #to_hash] old_ribbon the ribbon with old values
|
|
300
|
+
# @param [Ribbon, Ribbon::Raw, #to_hash] new_ribbon the ribbon with new values
|
|
301
|
+
# @return [Ribbon, Ribbon::Raw, Hash] old_ribbon, which will contain the
|
|
302
|
+
# results of the merge
|
|
312
303
|
# @yieldparam key the key which identifies both values
|
|
313
304
|
# @yieldparam old_value the value from old_ribbon
|
|
314
305
|
# @yieldparam new_value the value from new_ribbon
|
|
315
306
|
# @yieldreturn the object that will be used as the new value
|
|
316
|
-
# @since 0.
|
|
307
|
+
# @since 0.8.0
|
|
317
308
|
# @see merge!
|
|
318
309
|
# @see deep_merge
|
|
319
310
|
# @see extract_hash_from
|
|
@@ -321,74 +312,26 @@ class << Ribbon
|
|
|
321
312
|
deep :merge!, old_ribbon, new_ribbon, &block
|
|
322
313
|
end
|
|
323
314
|
|
|
324
|
-
# Tests whether the given object is an instance of Ribbon.
|
|
325
|
-
#
|
|
326
|
-
# @param object the object to be tested
|
|
327
|
-
# @return [true, false] whether the object is an instance of Ribbon
|
|
328
|
-
# @since 0.2.0
|
|
329
|
-
def instance?(object)
|
|
330
|
-
Ribbon === object
|
|
331
|
-
end
|
|
332
|
-
|
|
333
|
-
# Tests whether the given object is an instance of {Ribbon::Wrapper}.
|
|
334
|
-
#
|
|
335
|
-
# @param object the object to be tested
|
|
336
|
-
# @return [true, false] whether the object is an instance of {Ribbon::Wrapper}
|
|
337
|
-
# @since 0.2.0
|
|
338
|
-
def wrapped?(ribbon)
|
|
339
|
-
Ribbon::Wrapper === ribbon
|
|
340
|
-
end
|
|
341
|
-
|
|
342
|
-
# Wraps an object in a {Ribbon::Wrapper}.
|
|
343
|
-
#
|
|
344
|
-
# @param [Ribbon, Ribbon::Wrapper, #to_hash] object the object to be wrapped
|
|
345
|
-
# @return [Ribbon::Wrapper] a new wrapped ribbon
|
|
346
|
-
# @since 0.2.0
|
|
347
|
-
def wrap(object = ::Ribbon.new, &block)
|
|
348
|
-
Ribbon::Wrapper.new object, &block
|
|
349
|
-
end
|
|
350
|
-
|
|
351
|
-
# Returns the hash of a Ribbon. Will attempt to convert other objects.
|
|
352
|
-
#
|
|
353
|
-
# @param [Ribbon, Ribbon::Wrapper, #to_hash] parameter the object to convert
|
|
354
|
-
# @return [Hash] the resulting hash
|
|
355
|
-
# @since 0.2.1
|
|
356
|
-
def extract_hash_from(parameter)
|
|
357
|
-
case parameter
|
|
358
|
-
when Ribbon::Wrapper then parameter.internal_hash
|
|
359
|
-
when Ribbon then parameter.__hash__
|
|
360
|
-
else parameter.to_hash
|
|
361
|
-
end
|
|
362
|
-
end
|
|
363
|
-
|
|
364
|
-
# Deserializes the hash from the string using YAML and uses it to construct a
|
|
365
|
-
# new ribbon.
|
|
366
|
-
#
|
|
367
|
-
# @param [String] string a valid YAML string
|
|
368
|
-
# @return [Ribbon] a new Ribbon
|
|
369
|
-
# @since 0.4.7
|
|
370
|
-
def from_yaml(string)
|
|
371
|
-
Ribbon.new YAML.load(string)
|
|
372
|
-
end
|
|
373
|
-
|
|
374
315
|
private
|
|
375
316
|
|
|
376
|
-
# Common logic for deep merge methods.
|
|
377
|
-
# +:merge+ or +:merge!+, and denotes which method will be used to merge
|
|
378
|
-
# recursively.
|
|
317
|
+
# Common logic for deep merge methods.
|
|
379
318
|
#
|
|
319
|
+
# @param [:merge, :merge!] merge_method the method that will be used to merge
|
|
320
|
+
# recursively
|
|
321
|
+
# @param [Ribbon, Ribbon::Raw, #to_hash] old_ribbon the ribbon with old values
|
|
322
|
+
# @param [Ribbon, Ribbon::Raw, #to_hash] new_ribbon the ribbon with new values
|
|
380
323
|
# @yieldparam key the key which identifies both values
|
|
381
324
|
# @yieldparam old_value the value from old_ribbon
|
|
382
325
|
# @yieldparam new_value the value from new_ribbon
|
|
383
326
|
# @yieldreturn the object that will be used as the new value
|
|
384
|
-
# @since 0.
|
|
327
|
+
# @since 0.8.0
|
|
385
328
|
# @see merge!
|
|
386
329
|
# @see merge
|
|
387
330
|
# @see deep_merge
|
|
388
331
|
# @see deep_merge!
|
|
389
332
|
def deep(merge_method, old_ribbon, new_ribbon, &block)
|
|
390
333
|
send merge_method, old_ribbon, new_ribbon do |key, old_value, new_value|
|
|
391
|
-
if
|
|
334
|
+
if [old_value, new_value].all? { |value| compatible? value }
|
|
392
335
|
deep merge_method, old_value, new_value, &block
|
|
393
336
|
else
|
|
394
337
|
if block then block.call key, old_value, new_value
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class Ribbon
|
|
1
|
+
class Ribbon
|
|
2
2
|
|
|
3
3
|
# Extensions to the standard library.
|
|
4
4
|
#
|
|
@@ -8,6 +8,11 @@ class Ribbon < BasicObject
|
|
|
8
8
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
%w(
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
%w(
|
|
12
|
+
|
|
13
|
+
ribbon/core_extensions/array
|
|
14
|
+
ribbon/core_extensions/basic_object
|
|
15
|
+
ribbon/core_extensions/hash
|
|
16
|
+
ribbon/core_extensions/object
|
|
17
|
+
|
|
18
|
+
).each { |file| require file }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require 'ribbon'
|
|
2
2
|
|
|
3
|
-
class Ribbon
|
|
3
|
+
class Ribbon
|
|
4
4
|
module CoreExtensions
|
|
5
5
|
|
|
6
6
|
# Methods to work with ribbons in arrays.
|
|
@@ -9,37 +9,30 @@ class Ribbon < BasicObject
|
|
|
9
9
|
# @since 0.6.0
|
|
10
10
|
module Array
|
|
11
11
|
|
|
12
|
-
#
|
|
13
|
-
# otherwise returns an empty ribbon.
|
|
12
|
+
# Extracts the last argument as a ribbon or returns an empty one.
|
|
14
13
|
#
|
|
15
|
-
# @return [Ribbon] the
|
|
14
|
+
# @return [Ribbon] the ribbon at the end of this array
|
|
15
|
+
# @see #extract_raw_ribbon
|
|
16
16
|
def extract_ribbon!
|
|
17
17
|
case last
|
|
18
|
-
when Hash then Ribbon.new pop
|
|
18
|
+
when Hash, Ribbon::Raw then Ribbon.new pop
|
|
19
19
|
when Ribbon then pop
|
|
20
|
-
when Ribbon::Wrapper then pop.ribbon
|
|
21
20
|
else Ribbon.new
|
|
22
21
|
end
|
|
23
22
|
end
|
|
24
23
|
|
|
25
|
-
# Extracts the last argument as a wrapped ribbon, or returns an empty one.
|
|
26
|
-
# See #extract_ribbon! for details.
|
|
27
|
-
#
|
|
28
|
-
# @return [Ribbon::Wrapper] the wrapped Ribbon at the end of this array
|
|
29
|
-
def extract_wrapped_ribbon!
|
|
30
|
-
Ribbon.wrap extract_ribbon!
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# Same as #extract_ribbon!
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
# @return [Ribbon] the Ribbon at the end of this array
|
|
37
24
|
alias extract_options_as_ribbon! extract_ribbon!
|
|
38
25
|
|
|
39
|
-
#
|
|
26
|
+
# Extracts the last argument as a raw ribbon or returns an empty one.
|
|
40
27
|
#
|
|
41
|
-
# @return [Ribbon::
|
|
42
|
-
|
|
28
|
+
# @return [Ribbon::Raw] the raw ribbon at the end of this array
|
|
29
|
+
# @since 0.8.0
|
|
30
|
+
# @see #extract_ribbon!
|
|
31
|
+
def extract_raw_ribbon!
|
|
32
|
+
Ribbon::Raw.new extract_ribbon!
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
alias extract_options_as_raw_ribbon! extract_raw_ribbon!
|
|
43
36
|
|
|
44
37
|
end
|
|
45
38
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class Ribbon
|
|
1
|
+
class Ribbon
|
|
2
2
|
module CoreExtensions
|
|
3
3
|
|
|
4
4
|
# Some useful methods.
|
|
@@ -8,12 +8,16 @@ class Ribbon < BasicObject
|
|
|
8
8
|
module BasicObject
|
|
9
9
|
|
|
10
10
|
# Evaluates the block using +instance_eval+ if it takes no arguments;
|
|
11
|
-
# yields
|
|
11
|
+
# yields this object to it otherwise.
|
|
12
12
|
#
|
|
13
|
-
# @yieldparam [self] object this
|
|
14
|
-
# @return [Object, nil] the result of the block or nil if not given one
|
|
13
|
+
# @yieldparam [self] object this object
|
|
14
|
+
# @return [::Object, nil] the result of the block or nil if not given one
|
|
15
15
|
def __yield_or_eval__(&block)
|
|
16
|
-
if block.arity.zero?
|
|
16
|
+
if block.arity.zero?
|
|
17
|
+
instance_eval &block
|
|
18
|
+
else
|
|
19
|
+
block.call self
|
|
20
|
+
end unless block.nil?
|
|
17
21
|
end
|
|
18
22
|
|
|
19
23
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require 'ribbon'
|
|
2
2
|
|
|
3
|
-
class Ribbon
|
|
3
|
+
class Ribbon
|
|
4
4
|
module CoreExtensions
|
|
5
5
|
|
|
6
6
|
# Includes methods to convert hashes to ribbons.
|
|
@@ -9,29 +9,22 @@ class Ribbon < BasicObject
|
|
|
9
9
|
# @since 0.6.0
|
|
10
10
|
module Hash
|
|
11
11
|
|
|
12
|
-
# Converts this hash to a
|
|
12
|
+
# Converts this hash to a ribbon.
|
|
13
13
|
#
|
|
14
|
-
# @return a new
|
|
14
|
+
# @return [Ribbon] a new ribbon with the contents of this hash
|
|
15
15
|
def to_ribbon
|
|
16
16
|
Ribbon.new self
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
# Converts this hash to a Ribbon::Wrapper.
|
|
20
|
-
#
|
|
21
|
-
# @return a new wrapped Ribbon with the contents of this hash
|
|
22
|
-
def to_ribbon_wrapper
|
|
23
|
-
Ribbon.wrap self
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
# Same as #to_ribbon.
|
|
27
|
-
#
|
|
28
|
-
# @return a new Ribbon with the contents of this hash
|
|
29
19
|
alias to_rbon to_ribbon
|
|
30
20
|
|
|
31
|
-
#
|
|
21
|
+
# Converts this hash to a raw ribbon.
|
|
32
22
|
#
|
|
33
|
-
# @return a new
|
|
34
|
-
|
|
23
|
+
# @return [Ribbon::Raw] a new raw ribbon with the contents of this hash
|
|
24
|
+
# @since 0.8.0
|
|
25
|
+
def to_raw_ribbon
|
|
26
|
+
Ribbon.wrap self
|
|
27
|
+
end
|
|
35
28
|
|
|
36
29
|
end
|
|
37
30
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class Ribbon
|
|
1
|
+
class Ribbon
|
|
2
2
|
module CoreExtensions
|
|
3
3
|
|
|
4
4
|
# Methods available to all objects.
|
|
@@ -13,6 +13,9 @@ class Ribbon < BasicObject
|
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
%w(
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
%w(
|
|
17
|
+
|
|
18
|
+
ribbon/core_extensions/object/option_scope
|
|
19
|
+
ribbon/core_extensions/object/yield_or_eval
|
|
20
|
+
|
|
21
|
+
).each { |file| require file }
|
data/lib/ribbon/gem.rb
CHANGED
data/lib/ribbon/options.rb
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
require 'ribbon/core_extensions/array'
|
|
1
|
+
%w(
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
ribbon
|
|
4
|
+
ribbon/core_extensions/array
|
|
5
|
+
|
|
6
|
+
).each { |file| require file }
|
|
7
|
+
|
|
8
|
+
class Ribbon
|
|
5
9
|
|
|
6
10
|
# Applies options to all method calls.
|
|
7
11
|
#
|
|
@@ -23,10 +27,9 @@ class Ribbon < BasicObject
|
|
|
23
27
|
# the block immediately, if given one.
|
|
24
28
|
#
|
|
25
29
|
# @param receiver the object that will be receiving the methods
|
|
26
|
-
# @param [Ribbon, Ribbon::
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
# @see CoreExt::BasicObject#__yield_or_eval__
|
|
30
|
+
# @param [Ribbon, Ribbon::Raw, #to_hash] options the options that will be
|
|
31
|
+
# applied to all methods
|
|
32
|
+
# @see CoreExtensions::BasicObject#__yield_or_eval__
|
|
30
33
|
def initialize(receiver, options = {}, &block)
|
|
31
34
|
@receiver, @options = receiver, options
|
|
32
35
|
__yield_or_eval__ &block
|
data/lib/ribbon/raw.rb
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
%w(
|
|
2
|
+
|
|
3
|
+
ribbon
|
|
4
|
+
ribbon/core_extensions/basic_object
|
|
5
|
+
|
|
6
|
+
).each { |file| require file }
|
|
7
|
+
|
|
8
|
+
class Ribbon
|
|
9
|
+
|
|
10
|
+
# Ribbon with the least amount of helper methods defined.
|
|
11
|
+
#
|
|
12
|
+
# @author Matheus Afonso Martins Moreira
|
|
13
|
+
# @since 0.8.0
|
|
14
|
+
# @see Ribbon
|
|
15
|
+
class Raw < BasicObject
|
|
16
|
+
|
|
17
|
+
# The hash used internally.
|
|
18
|
+
#
|
|
19
|
+
# @return [Hash] the hash used by this Ribbon instance to store data
|
|
20
|
+
# @api private
|
|
21
|
+
def __hash__
|
|
22
|
+
@hash ||= (::Hash.new &::Ribbon::Raw.default_value_proc)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Initializes a new raw ribbon with the given values.
|
|
26
|
+
#
|
|
27
|
+
# If given a block, the raw ribbon will be yielded to it. If the block
|
|
28
|
+
# doesn't take any arguments, it will be evaluated in the context of the raw
|
|
29
|
+
# ribbon.
|
|
30
|
+
#
|
|
31
|
+
# All objects inside the hash will be {convert_all! converted}.
|
|
32
|
+
#
|
|
33
|
+
# @param [Ribbon, Ribbon::Raw, #to_hash] hash the hash with initial values
|
|
34
|
+
# @see CoreExtensions::BasicObject#__yield_or_eval__
|
|
35
|
+
def initialize(hash = {}, &block)
|
|
36
|
+
__hash__.merge! ::Ribbon.extract_hash_from hash
|
|
37
|
+
__yield_or_eval__ &block
|
|
38
|
+
::Ribbon::Raw.convert_all! self
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Fetches the value associated with the given key.
|
|
42
|
+
#
|
|
43
|
+
# If given a block, the value will be yielded to it. If the block doesn't take
|
|
44
|
+
# any arguments, it will be evaluated in the context of the value.
|
|
45
|
+
#
|
|
46
|
+
# @param key the key which identifies the value
|
|
47
|
+
# @return the value associated with the given key
|
|
48
|
+
# @see CoreExtensions::BasicObject#__yield_or_eval__
|
|
49
|
+
def [](key, &block)
|
|
50
|
+
value = ::Ribbon::Raw.convert __hash__[key]
|
|
51
|
+
value.__yield_or_eval__ &block
|
|
52
|
+
self[key] = value
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Associates the given values with the given key.
|
|
56
|
+
#
|
|
57
|
+
# @param key the key that will identify the values
|
|
58
|
+
# @param values the values that will be associated with the key
|
|
59
|
+
# @raise [ArgumentError] if the given key is a raw ribbon
|
|
60
|
+
# @example
|
|
61
|
+
# ribbon = Ribbon.new
|
|
62
|
+
#
|
|
63
|
+
# ribbon[:key] = :value
|
|
64
|
+
# ribbon[:key]
|
|
65
|
+
# # => :value
|
|
66
|
+
#
|
|
67
|
+
# ribbon[:key] = :multiple, :values
|
|
68
|
+
# ribbon[:key]
|
|
69
|
+
# # => [:multiple, :values]
|
|
70
|
+
def []=(key, *values)
|
|
71
|
+
raise ArgumentError, 'Raw Ribbons can not be used as hash keys' if ::Ribbon.raw? key
|
|
72
|
+
__hash__[key] = if values.size == 1 then values.first else values end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Handles the following cases:
|
|
76
|
+
#
|
|
77
|
+
# ribbon.method => ribbon[:method]
|
|
78
|
+
# ribbon.method value => ribbon[:method] = value
|
|
79
|
+
# ribbon.method &block => ribbon[:method, &block]
|
|
80
|
+
# ribbon.method value, &block => ribbon[:method] = value
|
|
81
|
+
# ribbon[:method, &block]
|
|
82
|
+
#
|
|
83
|
+
# ribbon.method = value => ribbon[:method] = value
|
|
84
|
+
#
|
|
85
|
+
# ribbon.method! value => ribbon[:method] = value
|
|
86
|
+
# self
|
|
87
|
+
# ribbon.method! &block => block.call ribbon[:method] if ribbon.__hash__.include? :method
|
|
88
|
+
# self
|
|
89
|
+
# ribbon.method! value, &block => ribbon[:method] = value
|
|
90
|
+
# block.call ribbon[:method]
|
|
91
|
+
# self
|
|
92
|
+
#
|
|
93
|
+
# ribbon.method? => ribbon.__hash__.fetch :method
|
|
94
|
+
# ribbon.method? value => ribbon.__hash__.fetch :method, value
|
|
95
|
+
# ribbon.method? &block => ribbon.__hash__.fetch :method, &block
|
|
96
|
+
# ribbon.method? value, &block => ribbon.__hash__.fetch :method, value, &block
|
|
97
|
+
def method_missing(method, *arguments, &block)
|
|
98
|
+
method_name = method.to_s
|
|
99
|
+
key = method_name.strip.gsub(/[=?!]$/, '').strip.intern
|
|
100
|
+
case method_name[-1]
|
|
101
|
+
when ?=
|
|
102
|
+
__send__ :[]=, key, *arguments
|
|
103
|
+
when ?!
|
|
104
|
+
__send__ :[]=, key, *arguments unless arguments.empty?
|
|
105
|
+
block.call self[key] if block and __hash__.include? key
|
|
106
|
+
self
|
|
107
|
+
when ??
|
|
108
|
+
begin __hash__.fetch key, *arguments, &block
|
|
109
|
+
rescue ::KeyError; nil end
|
|
110
|
+
else
|
|
111
|
+
__send__ :[]=, key, *arguments unless arguments.empty?
|
|
112
|
+
self[key, &block]
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Generates a simple and customizable human-readable string representation
|
|
117
|
+
# of this raw ribbon.
|
|
118
|
+
#
|
|
119
|
+
# @option options [#to_s] :separator (': ') separates the key/value pair
|
|
120
|
+
# @option options [#to_sym] :key (:to_s) will be sent to the key in order to
|
|
121
|
+
# convert it to a string.
|
|
122
|
+
# @option options [#to_sym] :value (:inspect) will be sent to the value in
|
|
123
|
+
# order to convert it to a string.
|
|
124
|
+
# @return [String] the string representation of this raw ribbon
|
|
125
|
+
def to_s(options = {})
|
|
126
|
+
__to_s_recursive__ ::Ribbon.extract_hash_from(options)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
alias inspect to_s
|
|
130
|
+
|
|
131
|
+
private
|
|
132
|
+
|
|
133
|
+
# Computes a string value recursively for the given ribbon, and all ribbons
|
|
134
|
+
# inside it, using the given options.
|
|
135
|
+
#
|
|
136
|
+
# @see #to_s
|
|
137
|
+
def __to_s_recursive__(options = {}, ribbon = self)
|
|
138
|
+
ksym = options.fetch(:key, :to_s).to_sym
|
|
139
|
+
vsym = options.fetch(:value, :inspect).to_sym
|
|
140
|
+
separator = options.fetch(:separator, ': ').to_s
|
|
141
|
+
'{%s}' % ribbon.__hash__.map do |k, v|
|
|
142
|
+
k = k.__send__ ksym
|
|
143
|
+
v = v.raw if ::Ribbon === v
|
|
144
|
+
v = if ::Ribbon.raw? v then __to_s_recursive__ options, v
|
|
145
|
+
else v.__send__ vsym end
|
|
146
|
+
'%s%s%s' % [ k, separator, v ]
|
|
147
|
+
end.join(', ')
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
class << Ribbon::Raw
|
|
155
|
+
|
|
156
|
+
alias [] new
|
|
157
|
+
|
|
158
|
+
# Proc used to store a new {Ribbon ribbon} instance as the value of a missing
|
|
159
|
+
# key.
|
|
160
|
+
#
|
|
161
|
+
# @return [Proc] the proc used when constructing new hashes
|
|
162
|
+
def default_value_proc
|
|
163
|
+
@default_value_proc ||= (proc { |hash, key| hash[key] = Ribbon.new })
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Converts hashes to ribbons. Will look inside arrays.
|
|
167
|
+
#
|
|
168
|
+
# @param object the object to convert
|
|
169
|
+
# @return the converted value
|
|
170
|
+
def convert(object)
|
|
171
|
+
case object
|
|
172
|
+
when Hash then Ribbon.new object
|
|
173
|
+
when Array then object.map { |element| convert element }
|
|
174
|
+
else object
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Converts all values inside the given ribbon.
|
|
179
|
+
#
|
|
180
|
+
# @param [Ribbon, Ribbon::Raw] ribbon the ribbon whose values are to be
|
|
181
|
+
# converted
|
|
182
|
+
# @return [Ribbon, Ribbon::Raw] the ribbon with all values converted
|
|
183
|
+
# @see convert
|
|
184
|
+
def convert_all!(ribbon)
|
|
185
|
+
ribbon.__hash__.each do |key, value|
|
|
186
|
+
ribbon[key] = case value
|
|
187
|
+
when Ribbon then convert_all! value.raw
|
|
188
|
+
when Ribbon::Raw then convert_all! value
|
|
189
|
+
else convert value
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
ribbon
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
end
|
data/ribbon.version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.8.0
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ribbon
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2012-
|
|
12
|
+
date: 2012-07-05 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: jewel
|
|
@@ -98,7 +98,7 @@ files:
|
|
|
98
98
|
- lib/ribbon/core_extensions/object/yield_or_eval.rb
|
|
99
99
|
- lib/ribbon/gem.rb
|
|
100
100
|
- lib/ribbon/options.rb
|
|
101
|
-
- lib/ribbon/
|
|
101
|
+
- lib/ribbon/raw.rb
|
|
102
102
|
- ribbon.gemspec
|
|
103
103
|
- ribbon.version
|
|
104
104
|
homepage: https://github.com/matheusmoreira/ribbon
|
|
@@ -115,7 +115,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
115
115
|
version: '0'
|
|
116
116
|
segments:
|
|
117
117
|
- 0
|
|
118
|
-
hash:
|
|
118
|
+
hash: 834480014355200814
|
|
119
119
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
120
|
none: false
|
|
121
121
|
requirements:
|
|
@@ -124,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
124
124
|
version: '0'
|
|
125
125
|
segments:
|
|
126
126
|
- 0
|
|
127
|
-
hash:
|
|
127
|
+
hash: 834480014355200814
|
|
128
128
|
requirements: []
|
|
129
129
|
rubyforge_project:
|
|
130
130
|
rubygems_version: 1.8.24
|
data/lib/ribbon/wrapper.rb
DELETED
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
require 'ribbon'
|
|
2
|
-
|
|
3
|
-
class Ribbon < BasicObject
|
|
4
|
-
|
|
5
|
-
# Wraps a Ribbon in order to provide general-purpose methods.
|
|
6
|
-
#
|
|
7
|
-
# Ribbons are designed to use methods as hash keys. In order to maximize the
|
|
8
|
-
# number of possibilities, many useful methods, including methods from Object,
|
|
9
|
-
# were left out and included in this class instead.
|
|
10
|
-
#
|
|
11
|
-
# You can use wrapped ribbons like an ordinary hash. Any undefined methods
|
|
12
|
-
# will be sent to the ribbon's hash. If the hash doesn't respond to the
|
|
13
|
-
# method, it will be sent to the ribbon itself.
|
|
14
|
-
#
|
|
15
|
-
# wrapper = Ribbon::Wrapper.new
|
|
16
|
-
#
|
|
17
|
-
# wrapper.a.b.c
|
|
18
|
-
# => {}
|
|
19
|
-
# wrapper.keys
|
|
20
|
-
# => [:a]
|
|
21
|
-
#
|
|
22
|
-
# Keep in mind that nested ribbons may or may not be wrapped:
|
|
23
|
-
#
|
|
24
|
-
# wrapper.a.b.c.keys
|
|
25
|
-
# => {}
|
|
26
|
-
# wrapper
|
|
27
|
-
# => {a: {b: {c: {keys: {}}}}}
|
|
28
|
-
#
|
|
29
|
-
# You can wrap and unwrap all ribbons inside:
|
|
30
|
-
#
|
|
31
|
-
# wrapper.wrap_all!
|
|
32
|
-
# wrapper.unwrap_all!
|
|
33
|
-
# @author Matheus Afonso Martins Moreira
|
|
34
|
-
# @since 0.2.0
|
|
35
|
-
# @see Ribbon
|
|
36
|
-
class Wrapper
|
|
37
|
-
|
|
38
|
-
# The wrapped Ribbon.
|
|
39
|
-
#
|
|
40
|
-
# @return [Ribbon] the ribbon wrapped by this instance
|
|
41
|
-
def ribbon
|
|
42
|
-
@ribbon ||= Ribbon.new
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# Wraps a Ribbon, another Wrapper's Ribbon or a hash.
|
|
46
|
-
#
|
|
47
|
-
# @param [Ribbon, Ribbon::Wrapper, #to_hash] ribbon the ribbon that will be
|
|
48
|
-
# wrapped
|
|
49
|
-
# @return [Ribbon] the wrapped Ribbon
|
|
50
|
-
def ribbon=(ribbon)
|
|
51
|
-
@ribbon = case ribbon
|
|
52
|
-
when Wrapper then ribbon.ribbon
|
|
53
|
-
when Ribbon then ribbon
|
|
54
|
-
else Ribbon.new ribbon.to_hash
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
# Wraps the given Ribbon, another Wrapper's Ribbon or a hash.
|
|
59
|
-
#
|
|
60
|
-
# If given a block, the wrapper will be yielded to it. If the block doesn't
|
|
61
|
-
# take any arguments, it will be evaluated in the context of the wrapper.
|
|
62
|
-
#
|
|
63
|
-
# @see #ribbon=
|
|
64
|
-
# @see Ribbon#initialize
|
|
65
|
-
def initialize(ribbon = Ribbon.new, &block)
|
|
66
|
-
self.ribbon = ribbon
|
|
67
|
-
__yield_or_eval__ &block
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
# The hash used by the wrapped Ribbon.
|
|
71
|
-
#
|
|
72
|
-
# @return [Hash] the internal hash of the Ribbon wrapped by this instance
|
|
73
|
-
# @since 0.5.0
|
|
74
|
-
def internal_hash
|
|
75
|
-
ribbon.__hash__
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
# Forwards the method, arguments and block to the wrapped Ribbon's hash, if
|
|
79
|
-
# it responds to the method, or to the ribbon itself otherwise.
|
|
80
|
-
def method_missing(method, *args, &block)
|
|
81
|
-
if (hash = internal_hash).respond_to? method then hash
|
|
82
|
-
else ribbon end.__send__ method, *args, &block
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
# Merges the contents of this wrapped Ribbon with the contents of the given
|
|
86
|
-
# Ribbon into a new Ribbon::Wrapper instance.
|
|
87
|
-
#
|
|
88
|
-
# @param [Ribbon, Ribbon::Wrapper, #to_hash] ribbon the ribbon with new
|
|
89
|
-
# values
|
|
90
|
-
# @return [Ribbon::Wrapper] a new wrapped ribbon containing the results of
|
|
91
|
-
# the merge
|
|
92
|
-
# @yieldparam key the key which identifies both values
|
|
93
|
-
# @yieldparam old_value the value from this wrapped Ribbon
|
|
94
|
-
# @yieldparam new_value the value from the given ribbon
|
|
95
|
-
# @yieldreturn the object that will be used as the new value
|
|
96
|
-
# @since 0.4.5
|
|
97
|
-
# @see #deep_merge!
|
|
98
|
-
# @see Ribbon.deep_merge
|
|
99
|
-
def deep_merge(ribbon, &block)
|
|
100
|
-
Ribbon.wrap Ribbon.deep_merge(self, ribbon, &block)
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
# Merges this wrapped Ribbon with the given Ribbon.
|
|
104
|
-
#
|
|
105
|
-
# @param [Ribbon, Ribbon::Wrapper, #to_hash] ribbon the ribbon with new
|
|
106
|
-
# values
|
|
107
|
-
# @return [self] this Ribbon::Wrapper instance
|
|
108
|
-
# @yieldparam key the key which identifies both values
|
|
109
|
-
# @yieldparam old_value the value from this wrapped Ribbon
|
|
110
|
-
# @yieldparam new_value the value from the given ribbon
|
|
111
|
-
# @yieldreturn the object that will be used as the new value
|
|
112
|
-
# @since 0.4.5
|
|
113
|
-
# @see #deep_merge
|
|
114
|
-
# @see Ribbon.deep_merge!
|
|
115
|
-
def deep_merge!(ribbon, &block)
|
|
116
|
-
Ribbon.deep_merge! self, ribbon, &block
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
# Wraps all ribbons contained by this wrapper's ribbon.
|
|
120
|
-
#
|
|
121
|
-
# @return [self] this Ribbon::Wrapper instance
|
|
122
|
-
# @since 0.3.0
|
|
123
|
-
def wrap_all!
|
|
124
|
-
wrap_all_recursive!
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
# Unwraps all ribbons contained by this wrapper's ribbon.
|
|
128
|
-
#
|
|
129
|
-
# @return [Ribbon] the Ribbon wrapped by this instance
|
|
130
|
-
# @since 0.3.0
|
|
131
|
-
def unwrap_all!
|
|
132
|
-
unwrap_all_recursive!
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
# Converts the wrapped Ribbon and all ribbons inside into hashes.
|
|
136
|
-
#
|
|
137
|
-
# @return [Hash] the converted contents of this wrapped Ribbon
|
|
138
|
-
def to_hash
|
|
139
|
-
to_hash_recursive
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
# Converts the wrapped ribbon to a hash and serializes it with YAML.
|
|
143
|
-
#
|
|
144
|
-
# @return [String] the YAML string that represents this Ribbon
|
|
145
|
-
# @see from_yaml
|
|
146
|
-
def to_yaml
|
|
147
|
-
to_hash.to_yaml
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
# Delegates to the wrapped Ribbon.
|
|
151
|
-
#
|
|
152
|
-
# @return [String] the string representation of this Ribbon::Wrapper
|
|
153
|
-
# @see Ribbon#to_s
|
|
154
|
-
def to_s
|
|
155
|
-
ribbon.to_s
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
private
|
|
159
|
-
|
|
160
|
-
# Converts the wrapped ribbon and all ribbons inside into hashes using
|
|
161
|
-
# recursion.
|
|
162
|
-
#
|
|
163
|
-
# @return [Hash] the converted contents of the wrapped Ribbon
|
|
164
|
-
def to_hash_recursive(ribbon = self.ribbon)
|
|
165
|
-
{}.tap do |hash|
|
|
166
|
-
ribbon.__hash__.each do |key, value|
|
|
167
|
-
hash[key] = case value
|
|
168
|
-
when Ribbon then to_hash_recursive value
|
|
169
|
-
when Ribbon::Wrapper then to_hash_recursive value.ribbon
|
|
170
|
-
else value
|
|
171
|
-
end
|
|
172
|
-
end
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
# Recursively wraps all ribbons and hashes inside.
|
|
177
|
-
#
|
|
178
|
-
# @return [self] this Ribbon::Wrapper instance
|
|
179
|
-
# @since 0.3.0
|
|
180
|
-
def wrap_all_recursive!(wrapper = self)
|
|
181
|
-
(hash = wrapper.internal_hash).each do |key, value|
|
|
182
|
-
hash[key] = case value
|
|
183
|
-
when Ribbon, Hash then wrap_all_recursive! Ribbon::Wrapper[value]
|
|
184
|
-
else value
|
|
185
|
-
end
|
|
186
|
-
end
|
|
187
|
-
wrapper
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
# Recursively unwraps all wrapped ribbons inside.
|
|
191
|
-
#
|
|
192
|
-
# @return [Ribbon] the Ribbon wrapped by this instance
|
|
193
|
-
# @since 0.3.0
|
|
194
|
-
def unwrap_all_recursive!(ribbon = self.ribbon)
|
|
195
|
-
ribbon.__hash__.each do |key, value|
|
|
196
|
-
ribbon[key] = case value
|
|
197
|
-
when Ribbon::Wrapper then unwrap_all_recursive! value.ribbon
|
|
198
|
-
else value
|
|
199
|
-
end
|
|
200
|
-
end
|
|
201
|
-
ribbon
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
class << Wrapper
|
|
207
|
-
|
|
208
|
-
# Wraps a Ribbon instance.
|
|
209
|
-
#
|
|
210
|
-
# @see #initialize
|
|
211
|
-
alias [] new
|
|
212
|
-
|
|
213
|
-
# Deserializes the hash from the +string+ using YAML and uses it to
|
|
214
|
-
# construct a new wrapped ribbon.
|
|
215
|
-
#
|
|
216
|
-
# @return [Ribbon::Wrapper] a new wrapped Ribbon
|
|
217
|
-
# @since 0.4.4
|
|
218
|
-
# @see #to_yaml
|
|
219
|
-
def from_yaml(string)
|
|
220
|
-
::Ribbon::Wrapper.new YAML.load(string)
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
end
|
|
224
|
-
end
|