Class: Axn::Core::FieldResolvers::Extract
- Inherits:
-
Object
- Object
- Axn::Core::FieldResolvers::Extract
- Defined in:
- lib/axn/core/field_resolvers/extract.rb
Instance Method Summary collapse
- #call ⇒ Object
-
#initialize(field:, provided_data:, options: {}, permit_method_call: false) ⇒ Extract
constructor
A new instance of Extract.
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 = @provided_data = provided_data @permit_method_call = permit_method_call end |
Instance Method Details
#call ⇒ Object
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 |