Class: CSVDecision::Matchers

Inherits:
Object
  • Object
show all
Defined in:
lib/csv_decision/matchers.rb,
lib/csv_decision.rb,
lib/csv_decision/matchers/range.rb,
lib/csv_decision/matchers/symbol.rb,
lib/csv_decision/matchers/numeric.rb,
lib/csv_decision/matchers/pattern.rb,
lib/csv_decision/matchers/constant.rb,
lib/csv_decision/matchers/function.rb

Overview

Methods to assign a matcher to data cells

Defined Under Namespace

Classes: Constant, Function, Matcher, Numeric, Pattern, Range, Symbol

Constant Summary

NEGATE =

Negation sign prefixed to ranges and functions.

'!'
EQUALS =

Cell constants and functions specified by prefixing the value with one of these 3 symbols

'==|:=|='
NUMERIC =

Regular expression used to recognise a numeric string with or without a decimal point.

'[-+]?\d*(?<decimal>\.?)\d*'
NUMERIC_RE =
regexp(NUMERIC)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Matchers

Returns a new instance of Matchers

Parameters:

  • options (Hash)

    Options hash supplied by the user.



113
114
115
116
# File 'lib/csv_decision/matchers.rb', line 113

def initialize(options)
  @ins = Matchers.ins_matchers(options)
  @outs = Matchers.outs_matchers(@ins)
end

Instance Attribute Details

#insArray<Matchers::Matcher> (readonly)

Returns Matchers for the input columns.

Returns:



107
108
109
# File 'lib/csv_decision/matchers.rb', line 107

def ins
  @ins
end

#outsArray<Matchers::Matcher> (readonly)

Returns Matchers for the output columns.

Returns:



110
111
112
# File 'lib/csv_decision/matchers.rb', line 110

def outs
  @outs
end

Class Method Details

.ins_matchers(options) ⇒ Object



98
99
100
# File 'lib/csv_decision/matchers.rb', line 98

def self.ins_matchers(options)
  options[:matchers].collect { |klass| klass.new(options) }
end

.numeric(value) ⇒ nil, ...

Validate a numeric value and convert it to an Integer or BigDecimal if a valid numeric string.

Parameters:

  • value (nil, String, Integer, BigDecimal)

Returns:

  • (nil, Integer, BigDecimal)


43
44
45
46
47
48
# File 'lib/csv_decision/matchers.rb', line 43

def self.numeric(value)
  return value if numeric?(value)
  return unless value.is_a?(String)

  to_numeric(value)
end

.numeric?(value) ⇒ Boolean

Returns Value is an Integer or a BigDecimal.

Parameters:

  • value (Object)

    Value from the input hash.

Returns:

  • (Boolean)

    Value is an Integer or a BigDecimal.



35
36
37
# File 'lib/csv_decision/matchers.rb', line 35

def self.numeric?(value)
  value.is_a?(Integer) || value.is_a?(BigDecimal)
end

.outs_matchers(matchers) ⇒ Object



102
103
104
# File 'lib/csv_decision/matchers.rb', line 102

def self.outs_matchers(matchers)
  matchers.select { |obj| OUTS_MATCHERS.include?(obj.class) }
end

.parse(columns:, matchers:, row:) ⇒ Array<(Array, ScanRow)>

Parse the supplied input columns for the row supplied using an array of matchers.

Parameters:

Returns:

  • (Array<(Array, ScanRow)>)

    Used to scan a table row against an input hash for matches.



71
72
73
74
75
76
77
78
79
80
81
# File 'lib/csv_decision/matchers.rb', line 71

def self.parse(columns:, matchers:, row:)
  # Build an array of column indexes requiring simple constant matches,
  # and a second array of columns requiring special matchers.
  scan_row = ScanRow.new

  row = scan_row.scan_columns(columns: columns, matchers: matchers, row: row)

  scan_row.freeze

  [row, scan_row.freeze]
end

.regexp(value) ⇒ Regexp

All regular expressions used for matching are anchored inside their own non-capturing group.

Parameters:

  • value (String)

    String used to form an anchored regular expression.

Returns:

  • (Regexp)

    Anchored, frozen regular expression.



25
26
27
# File 'lib/csv_decision/matchers.rb', line 25

def self.regexp(value)
  Regexp.new("\\A(?:#{value})\\z").freeze
end

.scan(matchers:, cell:) ⇒ false, Matchers::Proc

Scan the table cell against all matches.

Parameters:

Returns:

  • (false, Matchers::Proc)


88
89
90
91
92
93
94
95
96
# File 'lib/csv_decision/matchers.rb', line 88

def self.scan(matchers:, cell:)
  matchers.each do |matcher|
    proc = matcher.matches?(cell)
    return proc if proc
  end

  # Must be a simple constant
  false
end

.to_numeric(value) ⇒ nil, ...

Convert a numeric string into an Integer or BigDecimal.

Parameters:

  • value (String)

Returns:

  • (nil, Integer, BigDecimal)


54
55
56
57
# File 'lib/csv_decision/matchers.rb', line 54

def self.to_numeric(value)
  return unless (match = NUMERIC_RE.match(value))
  coerce_numeric(match, value)
end

Instance Method Details

#parse_ins(columns:, row:) ⇒ Array<(Array, ScanRow)>

Parse the row's input columns using the input matchers.

Parameters:

  • columns (Hash{Integer=>Columns::Entry})

    Input columns hash.

  • row (Array<String>)

    Data row being parsed.

Returns:

  • (Array<(Array, ScanRow)>)

    Used to scan a table row against an input hash for matches.



123
124
125
# File 'lib/csv_decision/matchers.rb', line 123

def parse_ins(columns:, row:)
  Matchers.parse(columns: columns, matchers: @ins, row: row)
end

#parse_outs(columns:, row:) ⇒ Array<(Array, ScanRow)>

Parse the row's output columns using the output matchers.

Parameters:

  • columns (Hash{Integer=>Columns::Entry})

    Input columns hash.

  • row (Array<String>)

    Data row being parsed.

Returns:

  • (Array<(Array, ScanRow)>)

    Used to scan a table row against an input hash for matches.



132
133
134
# File 'lib/csv_decision/matchers.rb', line 132

def parse_outs(columns:, row:)
  Matchers.parse(columns: columns, matchers: @outs, row: row)
end