Class: Axn::Core::FieldResolvers::Extract

Inherits:
Object
  • Object
show all
Defined in:
lib/axn/core/field_resolvers/extract.rb

Instance Method Summary collapse

Constructor Details

#initialize(field:, provided_data:, options: {}, permit_method_call: false) ⇒ Extract

Returns a new instance of Extract.



10
11
12
13
14
15
# File 'lib/axn/core/field_resolvers/extract.rb', line 10

def initialize(field:, provided_data:, options: {}, permit_method_call: false)
  @field = field
  @options = options
  @provided_data = provided_data
  @permit_method_call = permit_method_call
end

Instance Method Details

#callObject



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/axn/core/field_resolvers/extract.rb', line 17

def call
  # `Symbol#name` hands back the interned, frozen String rather than a fresh copy per read, and
  # `String#to_s` returns the receiver, so reading the path itself allocates nothing. This is a
  # per-read cost on the hottest path in the library: every top-level field resolves through
  # here, several times per call.
  path = field.is_a?(Symbol) ? field.name : field.to_s

  # An empty path names no segment and reads as the source itself, which is what an empty split
  # reduced to. Kept explicit so the single-segment shortcut below can't change it.
  return provided_data if path.empty?

  # One segment — every top-level field, and every subfield spelled against its own parent — is
  # the overwhelmingly common case, and needs neither the segment Array nor the reduce block.
  return resolve_segment(provided_data, path) unless path.include?(".")

  # A dotted path is resolved one segment at a time, re-dispatching on the type reached at
  # each step, so "items.count" behaves identically to `:count on :items`: the Hash segment
  # is read by key, the nested Array segment via its reader method. Digging the whole path off
  # the top-level source instead would push a String key into a nested Array and blow up.
  path.split(".").reduce(provided_data) { |current, segment| resolve_segment(current, segment) }
end