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:



72
73
74
75
# File 'lib/convenient_service/utils/array/find_yield.rb', line 72

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

Instance Attribute Details

#arrayObject (readonly)

Returns the value of attribute array.



59
60
61
# File 'lib/convenient_service/utils/array/find_yield.rb', line 59

def array
  @array
end

#blockObject (readonly)

Returns the value of attribute block.



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

def block
  @block
end

Instance Method Details

#callObject?

Returns Can be any type.



81
82
83
84
85
86
87
88
89
# File 'lib/convenient_service/utils/array/find_yield.rb', line 81

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

    return block_value if block_value
  end

  nil
end