Module: RepeaterMethods

Included in:
BlockRepeater::Repeater
Defined in:
lib/block_repeater/repeater_methods.rb

Overview

Additional methods for the Repeater class

Defined Under Namespace

Classes: MethodUnresponsiveError

Constant Summary collapse

UNTIL_METHOD_REGEX =
/until_((.*)_becomes_(.*)|(.*))/.freeze

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args, &block) ⇒ Object

If a method in the correct format is provided it will be converted into the conditional block for the Repeater class This expects either one or two method names which will be called against the result of repeating the main block. The correct format is ‘until_<method name>’ or ‘until_<method name>becomes<method name>’.

examples:

until_positive? Attempts to call the :positive? method on the result of the block repeat

until_count_becomes_positive? Attempts to call :count on the result of the block repeat, then :positive? on that result



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/block_repeater/repeater_methods.rb', line 22

def method_missing(method_name, *args, &block)
  if method_name.match UNTIL_METHOD_REGEX
    @manual_repeat = false
    @unresponsive_errors = []
    first_match = Regexp.last_match(1)
    second_match = Regexp.last_match(2)
    third_match = Regexp.last_match(3)

    if second_match && third_match
      final_result = self.until do |result|
        call_output = call_if_method_responsive(result, second_match)
        call_if_method_responsive(call_output, third_match) if @unresponsive_errors.empty?
      end
    else
      final_result = self.until do |result|
        call_if_method_responsive(result, first_match)
      end
    end
    raise MethodUnresponsiveError, "Methods were not compatible: #{@unresponsive_errors.uniq.join(', ')}" unless @unresponsive_errors.empty?
    final_result
  else
    super
  end
end

Instance Method Details

#call_if_method_responsive(value, method) ⇒ Object



51
52
53
54
55
56
57
58
# File 'lib/block_repeater/repeater_methods.rb', line 51

def call_if_method_responsive(value, method)
  method = method.to_sym
  if value.respond_to?(method)
    value.send(method)
  else
    @unresponsive_errors << "#{value.class.name} does not respond to method #{method}"
  end
end

#respond_to_missing?(method_name) ⇒ Boolean

Returns:

  • (Boolean)


47
48
49
# File 'lib/block_repeater/repeater_methods.rb', line 47

def respond_to_missing?(method_name, *)
  method_name.match UNTIL_METHOD_REGEX || super
end