class CSVDecision::Matchers

Cell matchers

Match table data cells against a valid decision table expression or a simple constant. @api private

Methods to assign a matcher to data cells @api private

Methods to assign a matcher to data cells @api private

Recognise expressions in table data cells. @api private

Methods to assign a matcher to data cells. @api private

Methods to assign a matcher to data cells @api private

Methods to assign a matcher to data cells. @api private

Recognise expressions in table data cells. @api private

Constants

EQUALS

Equality, cell constants and functions specified by prefixing the value with one of these 3 symbols.

EQUALS_RE

Match Regexp for equality

INEQUALITY

Symbols used for inequality

INEQUALITY_RE

Match Regexp for inequality

METHOD_NAME_RE

Method names are stricter than CSV column names.

NEGATE

Negation sign prefixed to ranges and functions.

NUMERIC

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

NUMERIC_RE

Attributes

ins[R]

@return [Array<Matchers::Matcher>] Matchers for the input columns.

outs[R]

@return [Array<Matchers::Matcher>] Matchers for the output columns.

Public Class Methods

compare?(lhs:, compare:, rhs:) click to toggle source

Compare one object with another if they both respond to the compare method.

@param lhs [Object] @param compare [Object] @param rhs [Object] @return [nil, Boolean]

# File lib/csv_decision/matchers.rb, line 133
def self.compare?(lhs:, compare:, rhs:)
  # Is the rhs the same class or a superclass of lhs, and does rhs respond to the
  # compare method?
  return lhs.send(compare, rhs) if lhs.is_a?(rhs.class) && rhs.respond_to?(compare)

  nil
end
new(options) click to toggle source

@param options (see CSVDecision.parse)

# File lib/csv_decision/matchers.rb, line 167
def initialize(options)
  matchers = options[:matchers].collect { |klass| klass.new(options) }
  @ins = matchers.select(&:ins?)
  @outs = matchers.select(&:outs?)
end
normalize_operator(operator) click to toggle source

Normalize the operators which are a variation on equals/assignment.

@param operator [String] @return [String]

# File lib/csv_decision/matchers.rb, line 95
def self.normalize_operator(operator)
  EQUALS_RE.match?(operator) ? '==' : operator
end
numeric(value) click to toggle source

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

@param value [nil, String, Integer, BigDecimal] @return [nil, Integer, BigDecimal]

# File lib/csv_decision/matchers.rb, line 109
def self.numeric(value)
  return value if value.is_a?(Integer) || value.is_a?(BigDecimal)
  return unless value.is_a?(String)

  to_numeric(value)
end
parse(columns:, matchers:, row:) click to toggle source

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

@param columns [Hash{Integer=>Columns::Entry}] Input columns hash. @param matchers [Array<Matchers::Matcher>] @param row [Array<String>] Data row being parsed. @return [Array<(Array, ScanRow)>] Used to scan a table row against an input hash for matches.

# File lib/csv_decision/matchers.rb, line 147
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

  # Scan the columns in the data row, and build an object to scan this row against
  # an input hash.
  # Convert values in the data row if not just a simple constant.
  row = scan_row.scan_columns(columns: columns, matchers: matchers, row: row)

  [row, scan_row]
end
regexp(value) click to toggle source

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

@param value [String] String used to form an anchored regular expression. @return [Regexp] Anchored, frozen regular expression.

# File lib/csv_decision/matchers.rb, line 71
def self.regexp(value)
  Regexp.new("\\A(?:#{value})\\z").freeze
end
to_numeric(value) click to toggle source

Convert a numeric string into an Integer or BigDecimal, otherwise return nil.

@param value [String] @return [nil, Integer, BigDecimal]

# File lib/csv_decision/matchers.rb, line 120
def self.to_numeric(value)
  return unless (match = NUMERIC_RE.match(value))

  return value.to_i if match['decimal'] == ''
  BigDecimal(value.chomp('.'))
end

Public Instance Methods

parse_ins(columns:, row:) click to toggle source

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

@param columns (see Matchers.parse) @param row (see Matchers.parse) @return (see Matchers.parse)

# File lib/csv_decision/matchers.rb, line 178
def parse_ins(columns:, row:)
  Matchers.parse(columns: columns, matchers: @ins, row: row)
end
parse_outs(columns:, row:) click to toggle source

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

@param columns (see Matchers.parse) @param row (see Matchers.parse) @return (see Matchers.parse)

# File lib/csv_decision/matchers.rb, line 187
def parse_outs(columns:, row:)
  Matchers.parse(columns: columns, matchers: @outs, row: row)
end