ryo.rb 0.5.5 → 0.5.7

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/specs.yml +2 -2
  3. data/.rubocop.yml +2 -0
  4. data/README.md +46 -27
  5. data/lib/ryo/basic_object.rb +7 -11
  6. data/lib/ryo/builder.rb +35 -54
  7. data/lib/ryo/enumerable.rb +62 -79
  8. data/lib/ryo/json.rb +6 -11
  9. data/lib/ryo/keywords.rb +16 -28
  10. data/lib/ryo/object.rb +6 -10
  11. data/lib/ryo/reflect.rb +54 -170
  12. data/lib/ryo/utils.rb +68 -0
  13. data/lib/ryo/version.rb +1 -1
  14. data/lib/ryo/yaml.rb +6 -11
  15. data/lib/ryo.rb +26 -37
  16. data/ryo.rb.gemspec +1 -0
  17. data/share/{ryo.rb/examples → examples/ryo.rb}/1.0_prototypes_point_object.rb +1 -0
  18. data/share/{ryo.rb/examples → examples/ryo.rb}/1.1_prototypes_ryo_fn.rb +1 -0
  19. data/share/{ryo.rb/examples → examples/ryo.rb}/2.0_iteration_each.rb +1 -0
  20. data/share/{ryo.rb/examples → examples/ryo.rb}/2.1_iteration_map.rb +1 -0
  21. data/share/{ryo.rb/examples → examples/ryo.rb}/2.2_iteration_ancestors.rb +1 -0
  22. data/share/examples/ryo.rb/3.0_recursion_ryo_from.rb +20 -0
  23. data/share/{ryo.rb/examples → examples/ryo.rb}/3.1_recursion_ryo_from_with_array.rb +5 -4
  24. data/share/{ryo.rb/examples → examples/ryo.rb}/3.2_recursion_ryo_from_with_openstruct.rb +3 -3
  25. data/share/{ryo.rb/examples → examples/ryo.rb}/4.0_basicobject_ryo_basicobject.rb +1 -0
  26. data/share/{ryo.rb/examples → examples/ryo.rb}/4.1_basicobject_ryo_basicobject_from.rb +1 -0
  27. data/share/{ryo.rb/examples → examples/ryo.rb}/5_collisions_resolution_strategy.rb +1 -0
  28. data/share/{ryo.rb/examples → examples/ryo.rb}/6_beyond_hash_objects.rb +1 -0
  29. data/share/{ryo.rb/examples → examples/ryo.rb}/7_ryo_memo.rb +1 -0
  30. data/share/ryo.rb/NEWS +11 -0
  31. data/spec/readme_spec.rb +2 -2
  32. data/spec/ryo_enumerable_spec.rb +1 -1
  33. data/spec/ryo_json_spec.rb +1 -1
  34. data/spec/ryo_keywords_spec.rb +1 -1
  35. data/spec/ryo_prototypes_spec.rb +1 -1
  36. data/spec/ryo_reflect_spec.rb +8 -0
  37. data/spec/ryo_spec.rb +1 -1
  38. data/spec/ryo_yaml_spec.rb +1 -1
  39. metadata +34 -18
  40. data/share/ryo.rb/examples/3.0_recursion_ryo_from.rb +0 -13
  41. /data/share/{ryo.rb/examples → examples/ryo.rb}/setup.rb +0 -0
  42. /data/{LICENSE → share/ryo.rb/LICENSE} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c611c0e990fe0cdfd09ede551e1b457e93af7765de379d64b5dbdf6495e2b766
4
- data.tar.gz: 24406b552991b2459da63847ff4b65071eb2e03cd846956e4a030f506fd5b908
3
+ metadata.gz: fbd00dab052b65ba426cdaa4ac900adc2daca2e23d1cbe5919a19e31bce30e45
4
+ data.tar.gz: 6757fd8be13568acb58fa6e0e5ec3ff395ab56bb14354dd6bbd024665998ff1d
5
5
  SHA512:
6
- metadata.gz: 28dca6bc48b5aab85c3e08698a60e460142114623b3f914db25bbe83fa767cdd70bcb8bb4bf68d07188cc884840d696cbba81b96683d10a690d939979e0f5dfc
7
- data.tar.gz: 325e58af48dc0cc6e85344ecedc006b6b331a2011432bc76069c374288bd676d2d918eee9807ee0194e8d2e31c0fe1dcbeda38b9c6a0f8982a1ea26ca0588457
6
+ metadata.gz: 13896d019d82fdb27003ead6dd60a34a8f2c09efb2aa018b74f520d8dbc5c79e775d5637ba66e715089221aad160dc7a00477cd0a908777ed9e5098c8eccf552
7
+ data.tar.gz: 3bfc72a7632226f9b67899045869fbec25a505276d5d595c5f13dc7a288924a4510d1b5e7ec69c120bff981fae887684953e6a223e481920dbf77d880c3448d1
@@ -19,5 +19,5 @@ jobs:
19
19
  - uses: ruby/setup-ruby@v1
20
20
  with:
21
21
  ruby-version: ${{ matrix.ruby }}
22
- - run: bundle install
23
- - run: rake ci
22
+ - run: ruby -S bundle install
23
+ - run: ruby -S bundle exec rake ci
data/.rubocop.yml CHANGED
@@ -22,6 +22,8 @@ Style/LambdaCall:
22
22
  Enabled: false
23
23
  Lint/AssignmentInCondition:
24
24
  Enabled: false
25
+ Style/ArgumentsForwarding:
26
+ Enabled: false
25
27
 
26
28
  ##
27
29
  # Disabled cops (rspec)
data/README.md CHANGED
@@ -16,6 +16,7 @@ method seen in the example returns an instance of
16
16
  [Ryo::Object](https://0x1eef.github.io/x/ryo.rb/Ryo/Object.html):
17
17
 
18
18
  ```ruby
19
+ #!/usr/bin/env ruby
19
20
  require "ryo"
20
21
 
21
22
  point_x = Ryo(x: 5)
@@ -35,6 +36,7 @@ will bind its `self` to the Ryo object it is assigned to, and when the function
35
36
  is called it will have access to the properties of the Ryo object:
36
37
 
37
38
  ```ruby
39
+ #!/usr/bin/env ruby
38
40
  require "ryo"
39
41
 
40
42
  point_x = Ryo(x: 5)
@@ -56,6 +58,7 @@ The following example demonstrates
56
58
  accessed for the first time. It is similar to a Ryo function:
57
59
 
58
60
  ```ruby
61
+ #!/usr/bin/env ruby
59
62
  require "ryo"
60
63
 
61
64
  point_x = Ryo(x: Ryo.memo { 5 })
@@ -87,6 +90,7 @@ is not implemented directly on a Ryo object.
87
90
  A demonstration of [`Ryo.each`](https://0x1eef.github.io/x/ryo.rb/Ryo.html#each-class_method):
88
91
 
89
92
  ```ruby
93
+ #!/usr/bin/env ruby
90
94
  require "ryo"
91
95
 
92
96
  point = Ryo(x: 10, y: 20)
@@ -115,6 +119,7 @@ and it returns a new copy of a Ryo object and its prototypes.
115
119
  A demonstration of [`Ryo.map!`](http://0x1eef.github.io/x/ryo.rb/Ryo/Enumerable.html#map!-instance_method):
116
120
 
117
121
  ```ruby
122
+ #!/usr/bin/env ruby
118
123
  require "ryo"
119
124
 
120
125
  point_x = Ryo(x: 2)
@@ -148,6 +153,7 @@ demonstrates using the `ancestors` option with
148
153
  [`Ryo.find`](https://0x1eef.github.io/x/ryo.rb/Ryo.html#find-class_method):
149
154
 
150
155
  ```ruby
156
+ #!/usr/bin/env ruby
151
157
  require "ryo"
152
158
 
153
159
  point_x = Ryo(x: 5)
@@ -167,23 +173,28 @@ p Ryo.find(point) { |k,v| v == 5 }.x # => point_x.x
167
173
  The [`Ryo.from`](https://0x1eef.github.io/x/ryo.rb/Ryo.html#from-class_method) method has
168
174
  the same interface as the [`Ryo`](https://0x1eef.github.io/x/ryo.rb/top-level-namespace.html#Ryo-instance_method)
169
175
  method, but it is implemented to recursively walk a Hash object and create Ryo objects
170
- from other Hash objects found along the way. Recursion is not the default behavior
171
- because it has the potential to be slow when given a complex Hash object that's
172
- very large - otherwise there shouldn't be a noticeable performance impact.
176
+ from other Hash objects found along the way.
173
177
 
174
178
  The following example demonstrates [`Ryo.from`](https://0x1eef.github.io/x/ryo.rb/Ryo.html#from-class_method):
175
179
 
176
180
  ```ruby
181
+ #!/usr/bin/env ruby
177
182
  require "ryo"
178
183
 
179
- point = Ryo.from({
180
- x: {to_i: 0},
181
- y: {to_i: 10}
184
+ person = Ryo.from({
185
+ name: "John",
186
+ age: 30,
187
+ address: {
188
+ street: "123 Main St",
189
+ city: "Anytown",
190
+ state: "AS",
191
+ zip: 12345
192
+ }
182
193
  })
183
- p [point.x.to_i, point.y.to_i]
194
+ p [person.name, person.age, person.address.city]
184
195
 
185
196
  ##
186
- # [0, 10]
197
+ # ["John", 30, "Anytown"]
187
198
  ```
188
199
 
189
200
  #### Ryo.from with an Array
@@ -194,17 +205,18 @@ An object that can't be turned into a Ryo object is left as-is. The following
194
205
  example demonstrates how that works in practice:
195
206
 
196
207
  ``` ruby
208
+ #!/usr/bin/env ruby
197
209
  require "ryo"
198
210
 
199
211
  points = Ryo.from([
200
- {x: {to_i: 2}},
212
+ {x: 2},
201
213
  "foobar",
202
- {y: {to_i: 4}}
214
+ {y: 4}
203
215
  ])
204
216
 
205
- p points[0].x.to_i
217
+ p points[0].x
206
218
  p points[1]
207
- p points[2].y.to_i
219
+ p points[2].y
208
220
 
209
221
  ##
210
222
  # 2
@@ -217,18 +229,17 @@ p points[2].y.to_i
217
229
  All methods that can create Ryo objects support turning a Struct, or OpenStruct object
218
230
  into a Ryo object. The following example demonstrates how
219
231
  [`Ryo.from`](https://0x1eef.github.io/x/ryo.rb/Ryo.html#from-class_method)
220
- can recursively turn an OpenStruct object into Ryo objects. The example also assigns
221
- a prototype to the Ryo object created from the OpenStruct:
232
+ can recursively turn an OpenStruct object into Ryo objects:
222
233
 
223
234
  ``` ruby
235
+ #!/usr/bin/env ruby
224
236
  require "ryo"
225
237
  require "ostruct"
226
238
 
227
239
  point = Ryo.from(
228
- OpenStruct.new(x: {to_i: 5}),
229
- Ryo.from(y: {to_i: 10})
240
+ OpenStruct.new(x: 5, y: 10)
230
241
  )
231
- p [point.x.to_i, point.y.to_i]
242
+ p [point.x, point.y]
232
243
 
233
244
  ##
234
245
  # [5, 10]
@@ -246,6 +257,7 @@ with fewer methods. The following example demonstrates
246
257
  how to create an instance of [Ryo::BasicObject](https://0x1eef.github.io/x/ryo.rb/Ryo/BasicObject.html):
247
258
 
248
259
  ```ruby
260
+ #!/usr/bin/env ruby
249
261
  require "ryo"
250
262
 
251
263
  point_x = Ryo::BasicObject(x: 0)
@@ -265,6 +277,7 @@ it returns instance(s) of [Ryo::BasicObject](https://0x1eef.github.io/x/ryo.rb/R
265
277
  instead:
266
278
 
267
279
  ```ruby
280
+ #!/usr/bin/env ruby
268
281
  require "ryo"
269
282
 
270
283
  point = Ryo::BasicObject.from({
@@ -281,18 +294,21 @@ p [point.x.to_i, point.y.to_i]
281
294
 
282
295
  #### Resolution strategy
283
296
 
284
- When a property and method collide, Ryo tries to find the best resolution. Since Ryo properties
285
- don't accept arguments, and methods can - we are able to distinguish a property from a method in
286
- many cases.
287
-
288
- Consider this example, where a property collides with the `Kernel#then` method. This example
289
- would work the same for other methods that accept a block and/or arguments:
297
+ When a property and method collide, Ryo tries to
298
+ find the best resolution. Because Ryo properties don't
299
+ accept arguments, and methods can - we can distinguish a
300
+ method from a Ryo property by the presence or absence of
301
+ an argument in at least some cases. Consider the following
302
+ example, where a property collides with the `Kernel#then` method:
290
303
 
291
304
  ```ruby
305
+ #!/usr/bin/env ruby
292
306
  require "ryo"
293
307
 
294
308
  ryo = Ryo::Object(then: 12)
309
+ # Resolves to Ryo property
295
310
  p ryo.then # => 12
311
+ # Resolves to Kernel#then
296
312
  p ryo.then { 34 } # => 34
297
313
  ```
298
314
 
@@ -300,10 +316,12 @@ p ryo.then { 34 } # => 34
300
316
 
301
317
  #### Duck typing
302
318
 
303
- The documentation has used simple terms to describe the objects that Ryo works
304
- with: Hash and Array objects. But that doesn't quite capture the fact that Ryo
305
- uses duck typing: any object that implements `#each_pair` is similar to a Hash,
306
- and any object that implements `#each` is similar to an Array. Note that only
319
+ The documentation has used simple terms to describe
320
+ the objects that Ryo works with: Hash and Array objects.
321
+ But that doesn't quite capture that Ryo is implemented with
322
+ duck typing: any object that implements `#each_pair`
323
+ could be used instead of a Hash, and any object that
324
+ implements `#each` could be used instead of an Array. Note that only
307
325
  [Ryo.from](https://0x1eef.github.io/x/ryo.rb/Ryo.html#from-class_method),
308
326
  [Ryo::Object.from](https://0x1eef.github.io/x/ryo.rb/Ryo/Object.html#from-class_method)
309
327
  and
@@ -313,6 +331,7 @@ can handle Array-like objects.
313
331
  The following example implements `#each_pair`:
314
332
 
315
333
  ``` ruby
334
+ #!/usr/bin/env ruby
316
335
  require "ryo"
317
336
 
318
337
  class Point
@@ -10,33 +10,30 @@ class Ryo::BasicObject < BasicObject
10
10
  ##
11
11
  # @param props (see Ryo::Builder.build)
12
12
  # @param prototype (see Ryo::Builder.build)
13
- #
14
13
  # @return [Ryo::BasicObject]
15
- # Returns an instance of {Ryo::BasicObject Ryo::BasicObject}.
14
+ # Returns an instance of {Ryo::BasicObject Ryo::BasicObject}
16
15
  def self.create(props, prototype = nil)
17
16
  ::Ryo::Builder.build(self, props, prototype)
18
17
  end
19
18
 
20
19
  ##
21
- # Creates a Ryo object by recursively walking a Hash object.
20
+ # Creates a Ryo object by recursively walking a Hash object
22
21
  #
23
22
  # @param props (see Ryo::Builder.recursive_build)
24
23
  # @param prototype (see Ryo::Builder.recursive_build)
25
- #
26
24
  # @return [Ryo::BasicObject]
27
- # Returns an instance of {Ryo::BasicObject Ryo::BasicObject}.
25
+ # Returns an instance of {Ryo::BasicObject Ryo::BasicObject}
28
26
  def self.from(props, prototype = nil)
29
27
  ::Ryo::Builder.recursive_build(self, props, prototype)
30
28
  end
31
29
 
32
30
  ##
33
- # Duplicates the internals of a Ryo object.
31
+ # Duplicates the internals of a Ryo object
34
32
  #
35
33
  # @param [Ryo::BasicObject] ryo
36
- # A Ryo object.
37
- #
34
+ # A Ryo object
38
35
  # @return [Ryo::BasicObject]
39
- # Returns a Ryo object.
36
+ # Returns a Ryo object
40
37
  def initialize_dup(ryo)
41
38
  ::Ryo.set_table_of(self, ::Ryo.table_of(ryo).dup)
42
39
  ::Ryo.extend!(self, ::Ryo)
@@ -50,9 +47,8 @@ end
50
47
  #
51
48
  # @param props (see Ryo::Builder.build)
52
49
  # @param prototype (see Ryo::Builder.build)
53
- #
54
50
  # @return [Ryo::BasicObject]
55
- # Returns an instance of {Ryo::BasicObject Ryo::BasicObject}.
51
+ # Returns an instance of {Ryo::BasicObject Ryo::BasicObject}
56
52
  def Ryo.BasicObject(props, prototype = nil)
57
53
  Ryo::BasicObject.create(props, prototype)
58
54
  end
data/lib/ryo/builder.rb CHANGED
@@ -1,29 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  ##
4
- # {Ryo::Builder Ryo::Builder} is a module that's used underneath Ryo's public
5
- # interface when creating instances of {Ryo::Object Ryo::Object}, and
6
- # {Ryo::BasicObject Ryo::BasicObject}. This module is not intended to be
7
- # used directly.
8
- #
4
+ # The {Ryo::Builder Ryo::Builder} module is responsible for
5
+ # the creation of instances of {Ryo::Object Ryo::Object},
6
+ # and {Ryo::BasicObject Ryo::BasicObject}. This module is
7
+ # not intended to be used directly.
9
8
  # @api private
10
9
  module Ryo::Builder
11
10
  ##
11
+ # @note
12
+ # When "props" is given as a Ryo object, a duplicate Ryo object is
13
+ # returned in its place
12
14
  # @param [<Ryo::Object, Ryo::BasicObject>] buildee
13
- # The class of the object to build.
14
- #
15
- # @param [<Hash, Ryo::Object, Ryo::BasicObject, #each_pair>] props
16
- # A Hash object, an object that implements "#each_pair", or a Ryo object.
17
- #
15
+ # @param [<#each_pair>] props
18
16
  # @param [<Ryo::Object, Ryo::BasicObject>, nil] prototype
19
- # The prototype, or nil for none.
20
- #
21
17
  # @return [<Ryo::Object, Ryo::BasicObject>]
22
- # Returns a Ryo object.
23
- #
24
- # @note
25
- # When "props" is given as a Ryo object, a duplicate Ryo object is
26
- # returned in its place.
18
+ # Returns a Ryo object
27
19
  def self.build(buildee, props, prototype = nil)
28
20
  if Ryo.ryo?(props)
29
21
  build(buildee, Ryo.table_of(props), prototype || Ryo.prototype_of(props))
@@ -38,7 +30,8 @@ module Ryo::Builder
38
30
  end
39
31
 
40
32
  ##
41
- # Creates a Ryo object by recursively walking a Hash object, or an Array of Hash objects.
33
+ # Creates a Ryo object by recursively walking a Hash object, or
34
+ # an Array of Hash objects
42
35
  #
43
36
  # @example
44
37
  # objects = Ryo.from([{x: 0, y: 0}, "foo", {point: {x: 0, y: 0}}])
@@ -46,22 +39,13 @@ module Ryo::Builder
46
39
  # objects[1] # => "foo"
47
40
  # objects[2].point.x # => 0
48
41
  #
49
- # @param buildee (see Ryo::Builder.build)
50
- #
51
- # @param [<Hash, Ryo::Object, Ryo::BasicObject, Array, #each_pair, #each> ] props
52
- # A Hash object, a Ryo object, or an array composed of either Hash / Ryo objects.
53
- #
54
- # @param prototype (see Ryo::Builder.build)
55
- #
42
+ # @note (see Ryo::Builder.build)
43
+ # @param (see Ryo::Builder.build)
56
44
  # @return (see Ryo::Builder.build)
57
- #
58
- # @note
59
- # When "props" is given as a Ryo object, a duplicate Ryo object is
60
- # returned in its place.
61
45
  def self.recursive_build(buildee, props, prototype = nil)
62
46
  if Ryo.ryo?(props)
63
47
  recursive_build(buildee, Ryo.table_of(props), prototype || Ryo.prototype_of(props))
64
- elsif eachless?(props)
48
+ elsif !respond_to_each?(props)
65
49
  raise TypeError, "The provided object does not implement #each / #each_pair"
66
50
  elsif !props.respond_to?(:each_pair)
67
51
  map(props) do
@@ -75,32 +59,29 @@ module Ryo::Builder
75
59
  end
76
60
  end
77
61
 
78
- ##
79
- # @private
80
- def self.map_value(buildee, value)
81
- if Ryo.ryo?(value) || eachless?(value)
82
- value
83
- elsif value.respond_to?(:each_pair)
84
- recursive_build(buildee, value)
85
- elsif value.respond_to?(:each)
86
- map(value) { map_value(buildee, _1) }
62
+ module Private
63
+ private
64
+
65
+ def map_value(buildee, value)
66
+ if Ryo.ryo?(value) || !respond_to_each?(value)
67
+ value
68
+ elsif value.respond_to?(:each_pair)
69
+ recursive_build(buildee, value)
70
+ elsif value.respond_to?(:each)
71
+ map(value) { map_value(buildee, _1) }
72
+ end
87
73
  end
88
- end
89
- private_class_method :map_value
90
74
 
91
- ##
92
- # @private
93
- def self.eachless?(value)
94
- !value.respond_to?(:each) && !value.respond_to?(:each_pair)
95
- end
96
- private_class_method :eachless?
75
+ def respond_to_each?(value)
76
+ value.respond_to?(:each) || value.respond_to?(:each_pair)
77
+ end
97
78
 
98
- ##
99
- # @private
100
- def self.map(obj)
101
- ary = []
102
- obj.each { ary.push(yield(_1)) }
103
- ary
79
+ def map(obj)
80
+ ary = []
81
+ obj.each { ary.push(yield(_1)) }
82
+ ary
83
+ end
104
84
  end
105
- private_class_method :map
85
+ private_constant :Private
86
+ extend Private
106
87
  end
@@ -1,14 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  ##
4
- # The {Ryo::Enumerable Ryo::Enumerable} module implements methods
5
- # for iterating through and performing operations on Ryo objects.
6
- # The methods implemented by this module are available as singleton
7
- # methods on the {Ryo} module.
4
+ # The {Ryo::Enumerable Ryo::Enumerable} module provides methods
5
+ # that are similar to Ruby's Enumerable module, and at the same
6
+ # time - intentionally different.
7
+ #
8
+ # For example: {Ryo::Enumerable Ryo::Enumerable}
9
+ # methods receive 'self' as an argument rather than from the
10
+ # surrounding context. The methods implemented by this
11
+ # module are available as singleton methods on the {Ryo Ryo}
12
+ # module.
8
13
  module Ryo::Enumerable
9
14
  ##
10
- # The {#each} methods iterates a Ryo object, and yields a key / value pair.
11
- # When a block is not given, {#each} returns an Enumerator.
15
+ # The {#each} method iterates through a Ryo object, and
16
+ # yields two parameters: a key, and a value
12
17
  #
13
18
  # @example
14
19
  # point_a = Ryo(x: 1, y: 2)
@@ -18,23 +23,19 @@ module Ryo::Enumerable
18
23
  # # ["y", 2]
19
24
  # # ["x", 1]
20
25
  #
21
- # @param [Ryo::Object, Ryo::BasicObject] ryo
22
- # A Ryo object.
23
- #
24
- # @param ancestors (see #each_ryo)
25
- #
26
+ # @param (see #each_ryo)
26
27
  # @return [<Enumerator, Array>]
27
- # Returns an Enumerator when a block is not given, otherwise returns an Array.
28
28
  def each(ryo, ancestors: nil)
29
29
  return enum_for(:each, ryo) unless block_given?
30
- each_ryo(ryo, ancestors: ancestors) do |_, key, value|
30
+ each_ryo(ryo, ancestors:) do |_, key, value|
31
31
  yield(key, value)
32
32
  end
33
33
  end
34
34
 
35
35
  ##
36
- # The {#each_ryo} method iterates through a Ryo object, and its prototypes.
37
- # {#each_ryo} yields three parameters: a Ryo object, a key, and a value.
36
+ # The {#each_ryo} method iterates through a Ryo object,
37
+ # and its prototypes. {#each_ryo} yields three parameters:
38
+ # a Ryo object, a key, and a value
38
39
  #
39
40
  # @example
40
41
  # point_a = Ryo(x: 1, y: 2)
@@ -45,15 +46,13 @@ module Ryo::Enumerable
45
46
  # # [point_a, "y", 2]
46
47
  #
47
48
  # @param [<Ryo::BasicObject, Ryo::Object>] ryo
48
- # A Ryo object.
49
- #
50
49
  # @param [Integer] ancestors
51
- # `ancestors` is an integer that determines how far up the prototype chain a
52
- # {Ryo::Enumerable Ryo::Enumerable} method can go. 0 covers a Ryo object,
53
- # and none of the prototypes in its prototype chain. 1 covers a Ryo object,
54
- # and one of the prototypes in its prototype chain - and so on. The default
55
- # behavior is to traverse the entire prototype chain.
56
- #
50
+ # "ancestors" is an integer that defines the traversal depth
51
+ # of a {Ryo::Enumerable Ryo::Enumerable} method. 0 covers a
52
+ # Ryo object, and none of the prototypes in its prototype
53
+ # chain. 1 covers a Ryo object, and one of the prototypes
54
+ # in its prototype chain - and so on. The default covers
55
+ # the entire prototype chain.
57
56
  # @return [<Ryo::BasicObject, Ryo::Object>]
58
57
  def each_ryo(ryo, ancestors: nil)
59
58
  proto_chain = [ryo, *prototype_chain_of(ryo)]
@@ -67,17 +66,19 @@ module Ryo::Enumerable
67
66
  end
68
67
 
69
68
  ##
70
- # The {#map} method creates a copy of a Ryo object, and then performs a map operation
71
- # on the copy and its prototypes.
69
+ # The {#map} method creates a copy of a Ryo object,
70
+ # and then performs a map operation on the copy and
71
+ # its prototypes
72
72
  #
73
- # @param (see #map!)
74
- # @return (see #map!)
73
+ # @param (see #each_ryo)
74
+ # @return [<Ryo::Object, Ryo::BasicObject>]
75
75
  def map(ryo, ancestors: nil, &b)
76
- map!(Ryo.dup(ryo), ancestors: ancestors, &b)
76
+ map!(Ryo.dup(ryo), ancestors:, &b)
77
77
  end
78
78
 
79
79
  ##
80
- # The {#map!} method performs an in-place map operation on a Ryo object, and its prototypes.
80
+ # The {#map!} method performs an in-place map operation
81
+ # on a Ryo object, and its prototypes
81
82
  #
82
83
  # @example
83
84
  # point = Ryo(x: 2, y: 4)
@@ -85,31 +86,28 @@ module Ryo::Enumerable
85
86
  # [point.x, point.y]
86
87
  # # => [4, 8]
87
88
  #
88
- # @param [<Ryo::Object, Ryo::BasicObject>] ryo
89
- # A Ryo object.
90
- #
91
- # @param ancestors (see #each_ryo)
92
- #
89
+ # @param (see #each_ryo)
93
90
  # @return [<Ryo::Object, Ryo::BasicObject>]
94
91
  def map!(ryo, ancestors: nil)
95
- each_ryo(ryo, ancestors: ancestors) do |ryo, key, value|
92
+ each_ryo(ryo, ancestors:) do |ryo, key, value|
96
93
  ryo[key] = yield(key, value)
97
94
  end
98
95
  end
99
96
 
100
97
  ##
101
- # The {#select} method creates a copy of a Ryo object, and then performs a filter operation
102
- # on the copy and its prototypes.
98
+ # The {#select} method creates a copy of a Ryo object, and
99
+ # then performs a filter operation on the copy and its
100
+ # prototypes
103
101
  #
104
- # @param (see #select!)
105
- # @return (see #select!)
102
+ # @param (see #each_ryo)
103
+ # @return [<Ryo::Object, Ryo::BasicObject>]
106
104
  def select(ryo, ancestors: nil, &b)
107
- select!(Ryo.dup(ryo), ancestors: ancestors, &b)
105
+ select!(Ryo.dup(ryo), ancestors:, &b)
108
106
  end
109
107
 
110
108
  ##
111
- # The {#select!} method performs an in-place filter operation on a Ryo object, and
112
- # its prototypes.
109
+ # The {#select!} method performs an in-place filter operation
110
+ # on a Ryo object, and its prototypes
113
111
  #
114
112
  # @example
115
113
  # point_a = Ryo(x: 1, y: 2, z: 3)
@@ -118,31 +116,27 @@ module Ryo::Enumerable
118
116
  # [point_b.x, point_b.y, point_b.z]
119
117
  # # => [1, 2, nil]
120
118
  #
121
- # @param [<Ryo::Object, Ryo::BasicObject>] ryo
122
- # A Ryo object.
123
- #
124
- # @param ancestors (see #each_ryo)
125
- #
119
+ # @param (see #each_ryo)
126
120
  # @return [<Ryo::Object, Ryo::BasicObject>]
127
121
  def select!(ryo, ancestors: nil)
128
- each_ryo(ryo, ancestors: ancestors) do |ryo, key, value|
122
+ each_ryo(ryo, ancestors:) do |ryo, key, value|
129
123
  delete(ryo, key) unless yield(key, value)
130
124
  end
131
125
  end
132
126
 
133
127
  ##
134
- # The {#reject} method creates a copy of a Ryo object, and then performs a filter operation
135
- # on the copy and its prototypes.
128
+ # The {#reject} method creates a copy of a Ryo object, and then
129
+ # performs a filter operation on the copy and its prototypes
136
130
  #
137
- # @param (see #reject!)
138
- # @return (see #reject!)
131
+ # @param (see #each_ryo)
132
+ # @return [<Ryo::Object, Ryo::BasicObject>]
139
133
  def reject(ryo, ancestors: nil, &b)
140
- reject!(Ryo.dup(ryo), ancestors: ancestors, &b)
134
+ reject!(Ryo.dup(ryo), ancestors:, &b)
141
135
  end
142
136
 
143
137
  ##
144
- # The {#reject!} method performs an in-place filter operation on a Ryo object, and
145
- # its prototypes.
138
+ # The {#reject!} method performs an in-place filter operation
139
+ # on a Ryo object, and its prototypes
146
140
  #
147
141
  # @example
148
142
  # point_a = Ryo(x: 1, y: 2, z: 3)
@@ -151,51 +145,39 @@ module Ryo::Enumerable
151
145
  # [point_b.x, point_b.y, point_b.z]
152
146
  # # => [1, 2, nil]
153
147
  #
154
- # @param [<Ryo::Object, Ryo::BasicObject>] ryo
155
- # A Ryo object.
156
- #
157
- # @param ancestors (see #each_ryo)
158
- #
148
+ # @param (see #each_ryo)
159
149
  # @return [<Ryo::Object, Ryo::BasicObject>]
160
150
  def reject!(ryo, ancestors: nil)
161
- each_ryo(ryo, ancestors: ancestors) do |ryo, key, value|
151
+ each_ryo(ryo, ancestors:) do |ryo, key, value|
162
152
  delete(ryo, key) if yield(key, value)
163
153
  end
164
154
  end
165
155
 
166
156
  ##
167
- # The {#any?} method iterates through a Ryo object, and its prototypes - yielding a
168
- # key / value pair to a block. If the block ever returns a truthy value, {#any?} will
169
- # break from the iteration and return true - otherwise false will be returned.
170
- #
171
- # @param ancestors (see #each_ryo)
157
+ # @param (see #each_ryo)
172
158
  # @return [Boolean]
159
+ # Returns true when the given block evaluates to
160
+ # a truthy value for at least one iteration
173
161
  def any?(ryo, ancestors: nil)
174
- each_ryo(ryo, ancestors: ancestors) do |_, key, value|
162
+ each_ryo(ryo, ancestors:) do |_, key, value|
175
163
  return true if yield(key, value)
176
164
  end
177
165
  false
178
166
  end
179
167
 
180
168
  ##
181
- # The {#all?} method iterates through a Ryo object, and its prototypes - yielding a
182
- # key / value pair to a block. If the block ever returns a falsey value, {#all?} will
183
- # break from the iteration and return false - otherwise true will be returned.
184
- #
185
- # @param ancestors (see #each_ryo)
169
+ # @param (see #each_ryo)
186
170
  # @return [Boolean]
171
+ # Returns true when the given block evaluates to a
172
+ # truthy value for every iteration
187
173
  def all?(ryo, ancestors: nil)
188
- each_ryo(ryo, ancestors: ancestors) do |_, key, value|
174
+ each_ryo(ryo, ancestors:) do |_, key, value|
189
175
  return false unless yield(key, value)
190
176
  end
191
177
  true
192
178
  end
193
179
 
194
180
  ##
195
- # The {#find} method iterates through a Ryo object, and its prototypes - yielding a
196
- # key / value pair to a block. If the block ever returns a truthy value, {#find} will
197
- # break from the iteration and return a Ryo object - otherwise nil will be returned.
198
- #
199
181
  # @example
200
182
  # point_a = Ryo(x: 5)
201
183
  # point_b = Ryo({y: 10}, point_a)
@@ -203,10 +185,11 @@ module Ryo::Enumerable
203
185
  # ryo = Ryo.find(point_c) { |key, value| value == 5 }
204
186
  # ryo == point_a # => true
205
187
  #
206
- # @param ancestors (see #each_ryo)
188
+ # @param (see #each_ryo)
207
189
  # @return [<Ryo::Object, Ryo::BasicObject>, nil]
190
+ # Returns a Ryo object, or nil
208
191
  def find(ryo, ancestors: nil)
209
- each_ryo(ryo, ancestors: ancestors) do |ryo, key, value|
192
+ each_ryo(ryo, ancestors:) do |ryo, key, value|
210
193
  return ryo if yield(key, value)
211
194
  end
212
195
  nil