Module: Ryo::Enumerable

Included in:
Ryo
Defined in:
lib/ryo/enumerable.rb

Overview

The Ryo::Enumerable module provides methods that are similar to Ruby’s Enumerable module, and at the same time - intentionally different.

For example: Ryo::Enumerable methods receive ‘self’ as an argument rather than from the surrounding context. The methods implemented by this module are available as singleton methods on the Ryo module.

Instance Method Summary collapse

Instance Method Details

#find(ryo, ancestors: nil) ⇒ <Ryo::Object, Ryo::BasicObject>?

Returns a Ryo object, or nil

Examples:

point_a = Ryo(x: 5)
point_b = Ryo({y: 10}, point_a)
point_c = Ryo({z: 15}, point_b)
ryo = Ryo.find(point_c) { |key, value| value == 5 }
ryo == point_a # => true

Parameters:

  • ryo (<Ryo::BasicObject, Ryo::Object>)
  • ancestors (Integer) (defaults to: nil)

    “ancestors” is an integer that defines the traversal depth of a Ryo::Enumerable method. 0 covers a Ryo object, and none of the prototypes in its prototype chain. 1 covers a Ryo object, and one of the prototypes in its prototype chain - and so on. The default covers the entire prototype chain.

Returns:



191
192
193
194
195
196
# File 'lib/ryo/enumerable.rb', line 191

def find(ryo, ancestors: nil)
  each_ryo(ryo, ancestors:) do |ryo, key, value|
    return ryo if yield(key, value)
  end
  nil
end

#each_ryo(ryo, ancestors: nil) ⇒ <Ryo::BasicObject, Ryo::Object>

The #each_ryo method iterates through a Ryo object, and its prototypes. #each_ryo yields three parameters: a Ryo object, a key, and a value

Examples:

point_a = Ryo(x: 1, y: 2)
point_b = Ryo({y: 3}, point_a)
Ryo.each_ryo(point_b) { |ryo, key, value| p [ryo, key, value] }
# [point_b, "y", 3]
# [point_a, "x", 1]
# [point_a, "y", 2]

Parameters:

  • ryo (<Ryo::BasicObject, Ryo::Object>)
  • ancestors (Integer) (defaults to: nil)

    “ancestors” is an integer that defines the traversal depth of a Ryo::Enumerable method. 0 covers a Ryo object, and none of the prototypes in its prototype chain. 1 covers a Ryo object, and one of the prototypes in its prototype chain - and so on. The default covers the entire prototype chain.

Returns:



57
58
59
60
61
62
63
64
65
66
# File 'lib/ryo/enumerable.rb', line 57

def each_ryo(ryo, ancestors: nil)
  proto_chain = [ryo, *prototype_chain_of(ryo)]
  ancestors ||= -1
  proto_chain[0..ancestors].each do |ryo|
    properties_of(ryo).each do |key|
      yield(ryo, key, ryo[key])
    end
  end
  ryo
end

#map(ryo, ancestors: nil, &b) ⇒ <Ryo::Object, Ryo::BasicObject>

The #map method creates a copy of a Ryo object, and then performs a map operation on the copy and its prototypes

Parameters:

  • ryo (<Ryo::BasicObject, Ryo::Object>)
  • ancestors (Integer) (defaults to: nil)

    “ancestors” is an integer that defines the traversal depth of a Ryo::Enumerable method. 0 covers a Ryo object, and none of the prototypes in its prototype chain. 1 covers a Ryo object, and one of the prototypes in its prototype chain - and so on. The default covers the entire prototype chain.

Returns:



75
76
77
# File 'lib/ryo/enumerable.rb', line 75

def map(ryo, ancestors: nil, &b)
  map!(Ryo.dup(ryo), ancestors:, &b)
end

#map!(ryo, ancestors: nil) ⇒ <Ryo::Object, Ryo::BasicObject>

The #map! method performs an in-place map operation on a Ryo object, and its prototypes

Examples:

point = Ryo(x: 2, y: 4)
Ryo.map!(point) { _2 * 2 }
[point.x, point.y]
# => [4, 8]

Parameters:

  • ryo (<Ryo::BasicObject, Ryo::Object>)
  • ancestors (Integer) (defaults to: nil)

    “ancestors” is an integer that defines the traversal depth of a Ryo::Enumerable method. 0 covers a Ryo object, and none of the prototypes in its prototype chain. 1 covers a Ryo object, and one of the prototypes in its prototype chain - and so on. The default covers the entire prototype chain.

Returns:



91
92
93
94
95
# File 'lib/ryo/enumerable.rb', line 91

def map!(ryo, ancestors: nil)
  each_ryo(ryo, ancestors:) do |ryo, key, value|
    ryo[key] = yield(key, value)
  end
end

#select(ryo, ancestors: nil, &b) ⇒ <Ryo::Object, Ryo::BasicObject>

The #select method creates a copy of a Ryo object, and then performs a filter operation on the copy and its prototypes

Parameters:

  • ryo (<Ryo::BasicObject, Ryo::Object>)
  • ancestors (Integer) (defaults to: nil)

    “ancestors” is an integer that defines the traversal depth of a Ryo::Enumerable method. 0 covers a Ryo object, and none of the prototypes in its prototype chain. 1 covers a Ryo object, and one of the prototypes in its prototype chain - and so on. The default covers the entire prototype chain.

Returns:



104
105
106
# File 'lib/ryo/enumerable.rb', line 104

def select(ryo, ancestors: nil, &b)
  select!(Ryo.dup(ryo), ancestors:, &b)
end

#select!(ryo, ancestors: nil) ⇒ <Ryo::Object, Ryo::BasicObject>

The #select! method performs an in-place filter operation on a Ryo object, and its prototypes

Examples:

point_a = Ryo(x: 1, y: 2, z: 3)
point_b = Ryo({z: 4}, point_a)
Ryo.select!(point_b) { |key, value| %w(x y).include?(key) }
[point_b.x, point_b.y, point_b.z]
# => [1, 2, nil]

Parameters:

  • ryo (<Ryo::BasicObject, Ryo::Object>)
  • ancestors (Integer) (defaults to: nil)

    “ancestors” is an integer that defines the traversal depth of a Ryo::Enumerable method. 0 covers a Ryo object, and none of the prototypes in its prototype chain. 1 covers a Ryo object, and one of the prototypes in its prototype chain - and so on. The default covers the entire prototype chain.

Returns:



121
122
123
124
125
# File 'lib/ryo/enumerable.rb', line 121

def select!(ryo, ancestors: nil)
  each_ryo(ryo, ancestors:) do |ryo, key, value|
    delete(ryo, key) unless yield(key, value)
  end
end

#reject(ryo, ancestors: nil, &b) ⇒ <Ryo::Object, Ryo::BasicObject>

The #reject method creates a copy of a Ryo object, and then performs a filter operation on the copy and its prototypes

Parameters:

  • ryo (<Ryo::BasicObject, Ryo::Object>)
  • ancestors (Integer) (defaults to: nil)

    “ancestors” is an integer that defines the traversal depth of a Ryo::Enumerable method. 0 covers a Ryo object, and none of the prototypes in its prototype chain. 1 covers a Ryo object, and one of the prototypes in its prototype chain - and so on. The default covers the entire prototype chain.

Returns:



133
134
135
# File 'lib/ryo/enumerable.rb', line 133

def reject(ryo, ancestors: nil, &b)
  reject!(Ryo.dup(ryo), ancestors:, &b)
end

#reject!(ryo, ancestors: nil) ⇒ <Ryo::Object, Ryo::BasicObject>

The #reject! method performs an in-place filter operation on a Ryo object, and its prototypes

Examples:

point_a = Ryo(x: 1, y: 2, z: 3)
point_b = Ryo({z: 4}, point_a)
Ryo.reject!(point_b) { |key, value| value > 2 }
[point_b.x, point_b.y, point_b.z]
# => [1, 2, nil]

Parameters:

  • ryo (<Ryo::BasicObject, Ryo::Object>)
  • ancestors (Integer) (defaults to: nil)

    “ancestors” is an integer that defines the traversal depth of a Ryo::Enumerable method. 0 covers a Ryo object, and none of the prototypes in its prototype chain. 1 covers a Ryo object, and one of the prototypes in its prototype chain - and so on. The default covers the entire prototype chain.

Returns:



150
151
152
153
154
# File 'lib/ryo/enumerable.rb', line 150

def reject!(ryo, ancestors: nil)
  each_ryo(ryo, ancestors:) do |ryo, key, value|
    delete(ryo, key) if yield(key, value)
  end
end

#any?(ryo, ancestors: nil) ⇒ Boolean

Returns true when the given block evaluates to a truthy value for at least one iteration

Parameters:

  • ryo (<Ryo::BasicObject, Ryo::Object>)
  • ancestors (Integer) (defaults to: nil)

    “ancestors” is an integer that defines the traversal depth of a Ryo::Enumerable method. 0 covers a Ryo object, and none of the prototypes in its prototype chain. 1 covers a Ryo object, and one of the prototypes in its prototype chain - and so on. The default covers the entire prototype chain.

Returns:

  • (Boolean)

    Returns true when the given block evaluates to a truthy value for at least one iteration



161
162
163
164
165
166
# File 'lib/ryo/enumerable.rb', line 161

def any?(ryo, ancestors: nil)
  each_ryo(ryo, ancestors:) do |_, key, value|
    return true if yield(key, value)
  end
  false
end

#all?(ryo, ancestors: nil) ⇒ Boolean

Returns true when the given block evaluates to a truthy value for every iteration

Parameters:

  • ryo (<Ryo::BasicObject, Ryo::Object>)
  • ancestors (Integer) (defaults to: nil)

    “ancestors” is an integer that defines the traversal depth of a Ryo::Enumerable method. 0 covers a Ryo object, and none of the prototypes in its prototype chain. 1 covers a Ryo object, and one of the prototypes in its prototype chain - and so on. The default covers the entire prototype chain.

Returns:

  • (Boolean)

    Returns true when the given block evaluates to a truthy value for every iteration



173
174
175
176
177
178
# File 'lib/ryo/enumerable.rb', line 173

def all?(ryo, ancestors: nil)
  each_ryo(ryo, ancestors:) do |_, key, value|
    return false unless yield(key, value)
  end
  true
end

#each(ryo, ancestors: nil) ⇒ <Enumerator, Array>

The #each method iterates through a Ryo object, and yields two parameters: a key, and a value

Examples:

point_a = Ryo(x: 1, y: 2)
point_b = Ryo(y: 1)
Ryo.each(point_b) { p [_1, _2] }
# ["y", 1]
# ["y", 2]
# ["x", 1]

Parameters:

  • ryo (<Ryo::BasicObject, Ryo::Object>)
  • ancestors (Integer) (defaults to: nil)

    “ancestors” is an integer that defines the traversal depth of a Ryo::Enumerable method. 0 covers a Ryo object, and none of the prototypes in its prototype chain. 1 covers a Ryo object, and one of the prototypes in its prototype chain - and so on. The default covers the entire prototype chain.

Returns:

  • (<Enumerator, Array>)


28
29
30
31
32
33
# File 'lib/ryo/enumerable.rb', line 28

def each(ryo, ancestors: nil)
  return enum_for(:each, ryo) unless block_given?
  each_ryo(ryo, ancestors:) do |_, key, value|
    yield(key, value)
  end
end