Module: Janeway::Interpreters::IterationHelper

Overview

Mixin for interpreter classes that yield to a block

Constant Summary collapse

PASS_ALL =

Sentinel block used by Interpreter#make_deleter to turn a DeleteIf into an unconditional deleter. equal?-comparable so future fast paths (bulk clear) can detect it.

proc { true }.freeze

Instance Method Summary collapse

Instance Method Details

#make_yield_proc(&block) ⇒ Proc

Returns a Proc that yields the correct number of parameters to a block

block.arity is -1 when no block is given, and an enumerator is being returned

Returns:

  • (Proc)

    which takes 3 parameters



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/janeway/interpreters/iteration_helper.rb', line 17

def make_yield_proc(&block)
  # Bind the block locally so the returned proc captures a local, not the
  # containing instance's @block ivar (avoids an ivar read per yield).
  b = block
  if block.arity.negative?
    # Yield just the value to an enumerator, to enable instance method calls on
    # matched values like this: enum.delete_if(&:even?)
    proc { |value, _parent, _path| b.call(value) }
  elsif block.arity > 3
    # Only do the work of constructing the normalized path when it is actually used
    proc { |value, parent, path| b.call(value, parent, path.last, normalized_path(path)) }
  else
    # block arity is 1, 2 or 3. Send all 3 parameters regardless.
    proc { |value, parent, path| b.call(value, parent, path.last) }
  end
end

#normalized_path(components) ⇒ String

Convert the list of path elements into a normalized query string.

This form uses a subset of jsonpath that unambiguously points to a value using only name and index selectors. Name selectors must use bracket notation, not shorthand.

Parameters:

  • components (Array<String, Integer>)

Returns:

  • (String)

See Also:



44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/janeway/interpreters/iteration_helper.rb', line 44

def normalized_path(components)
  # First component is the root identifer, the remaining components are
  # all index selectors or name selectors.
  # Build the result string in a single pass — avoids `components[1..]`
  # (slice allocation) plus `.map { ... }.join` (intermediate Array).
  result = +'$'
  i = 1
  while i < components.size
    result << NormalizedPath.normalize(components[i])
    i += 1
  end
  result
end