Class: Ast::Merge::CompositeMatchRefiner

Inherits:
Object
  • Object
show all
Defined in:
lib/ast/merge/composite_match_refiner.rb

Overview

Chains multiple match refiners sequentially.

Each refiner in the pipeline processes the unmatched nodes left over from the previous pass. This allows combining refiners that target different node types or use different scoring strategies (e.g., Levenshtein for paragraphs + Jaccard for comments).

Implements the same #call(template_nodes, dest_nodes, context) interface as MatchRefinerBase, so it can be passed anywhere a single refiner is accepted.

Examples:

Combining content and token refiners

composite = CompositeMatchRefiner.new(
  ContentMatchRefiner.new(threshold: 0.7, node_types: [:paragraph]),
  TokenMatchRefiner.new(threshold: 0.35, node_types: [:comment]),
)
merger = SmartMerger.new(template, dest, match_refiner: composite)

Adding refiners after construction

composite = CompositeMatchRefiner.new
composite << ContentMatchRefiner.new(threshold: 0.6)
composite << TokenMatchRefiner.new(threshold: 0.35)

See Also:

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*refiners) ⇒ CompositeMatchRefiner

Initialize with zero or more refiners.

Parameters:

  • refiners (Array<#call>)

    Refiners to chain, in execution order



35
36
37
# File 'lib/ast/merge/composite_match_refiner.rb', line 35

def initialize(*refiners)
  @refiners = refiners.flatten.compact
end

Instance Attribute Details

#refinersArray<#call> (readonly)

Returns Ordered list of refiners in the pipeline.

Returns:

  • (Array<#call>)

    Ordered list of refiners in the pipeline



30
31
32
# File 'lib/ast/merge/composite_match_refiner.rb', line 30

def refiners
  @refiners
end

Instance Method Details

#<<(refiner) ⇒ self

Append a refiner to the pipeline.

Parameters:

  • refiner (#call)

    A match refiner

Returns:

  • (self)


43
44
45
46
# File 'lib/ast/merge/composite_match_refiner.rb', line 43

def <<(refiner)
  @refiners << refiner
  self
end

#call(template_nodes, dest_nodes, context = {}) ⇒ Array<MatchRefinerBase::MatchResult>

Run all refiners sequentially.

Each refiner receives the unmatched nodes remaining after previous refiners have consumed their matches. All matches are accumulated and returned as a single flat array.

Parameters:

  • template_nodes (Array)

    Unmatched template nodes

  • dest_nodes (Array)

    Unmatched destination nodes

  • context (Hash) (defaults to: {})

    Additional context passed to each refiner

Returns:



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/ast/merge/composite_match_refiner.rb', line 58

def call(template_nodes, dest_nodes, context = {})
  all_matches = []
  remaining_template = template_nodes.dup
  remaining_dest = dest_nodes.dup

  refiners.each do |refiner|
    next if remaining_template.empty? || remaining_dest.empty?

    matches = Array(refiner.call(remaining_template, remaining_dest, context))
    next if matches.empty?

    matched_template = matches.map(&:template_node)
    matched_dest = matches.map(&:dest_node)

    remaining_template -= matched_template
    remaining_dest -= matched_dest
    all_matches.concat(matches)
  end

  all_matches
end

#empty?Boolean

Whether this composite has any refiners.

Returns:

  • (Boolean)


83
84
85
# File 'lib/ast/merge/composite_match_refiner.rb', line 83

def empty?
  refiners.empty?
end

#sizeInteger

Number of refiners in the pipeline.

Returns:

  • (Integer)


90
91
92
# File 'lib/ast/merge/composite_match_refiner.rb', line 90

def size
  refiners.size
end