Class: ConvenientService::Utils::Array::FindYield

Inherits:
Support::Command show all
Defined in:
lib/convenient_service/utils/array/find_yield.rb

Overview

Examples:

Preconditions (pseudo-real world):

- Both `match?` and `match` do exactly the same thing, only their return values are different.
- `match?` returns `true` when the string matches the regex, otherwise - `false`.
- `match` returns regex match data when the string matches the regex, otherwise - `nil`.
- Regex matching is a very resource-heavy process.

- `test` is defined like this:
  def test
    string = strings.find { |string| string.match?(regexp) }

    return unless string

    string.match(regexp)
  end

- To simplify the example, imagine that `strings` return an array with only one string and that string matches regex.
  def strings
    ["foo bar"]
  end

  def regexp
    /\w+/
  end
- This way regex matching (a very resource-heavy process) is executed twice.
- First time during the `match?` method call.
- The second time during the `match` method call.

Task:
- How to implement `test` in a way that regexp matching (very resource-heavy process) is executed only once for the preconditions above?

Solution:
- Use `ConvenientService::Utils::Array.find_yield`
- `test` should be rewritten like this:
  def test
    ConvenientService::Utils::Array.find_yield(strings) { |string| string.match(regexp) }
  end

Inspiration:
- https://github.com/rubyworks/facets/blob/3.1.0/lib/core/facets/enumerable/find_yield.rb#L28
- https://stackoverflow.com/a/38457218/12201472

Note: `String#match?` and `String#match` docs.
- https://ruby-doc.org/core-2.7.0/String.html#method-i-match-3F
- https://ruby-doc.org/core-2.7.0/String.html#method-i-match

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Support::Command

[], call

Constructor Details

#initialize(array, &block) ⇒ void

Parameters:



77
78
79
80
# File 'lib/convenient_service/utils/array/find_yield.rb', line 77

def initialize(array, &block)
  @array = array
  @block = block
end

Instance Attribute Details

#arrayObject (readonly)

Returns the value of attribute array.



64
65
66
# File 'lib/convenient_service/utils/array/find_yield.rb', line 64

def array
  @array
end

#blockObject (readonly)

Returns the value of attribute block.



70
71
72
# File 'lib/convenient_service/utils/array/find_yield.rb', line 70

def block
  @block
end

Instance Method Details

#callObject?

Returns Can be any type.



86
87
88
89
90
91
92
93
94
# File 'lib/convenient_service/utils/array/find_yield.rb', line 86

def call
  array.each do |item|
    block_value = block.call(item)

    return block_value if block_value
  end

  nil
end