class PatternAction

Public Class Methods

new(action_maps_array, message_callables = []) click to toggle source
Calls superclass method NoPatternNoAction::new
# File lib/datalackeylib.rb, line 155
def initialize(action_maps_array, message_callables = [])
  raise ArgumentError, 'action_maps_array is empty' unless action_maps_array.is_a?(Array) && !action_maps_array.empty?
  super()
  @pattern2act = { }
  @fixed2act = { }
  @generators = message_callables.is_a?(Array) ? message_callables.clone : [ message_callables ]
  action_maps_array.each do |m|
    raise ArgumentError, 'Action map is not a map.' unless m.is_a? Hash
    fill_pattern2action_maps([], m)
  end
  @pattern2act.each_value(&:uniq!)
  @fixed2act.each_value(&:uniq!)
  raise ArgumentError, 'No patterns.' if @pattern2act.empty? && @fixed2act.empty?
end

Public Instance Methods

best_match(message_array) click to toggle source
# File lib/datalackeylib.rb, line 231
def best_match(message_array)
  return [ @fixed2act[message_array], [] ] if @fixed2act.key? message_array
  best_length = 0
  best = nil
  best_vars = []
  @pattern2act.each_pair do |pattern, act|
    next if message_array.length + 1 < pattern.length
    next if pattern.last != :rest && message_array.length != pattern.length
    length = 0
    exact_length = 0
    found = true
    vars = []
    pattern.each_index do |idx|
      if pattern[idx] == :rest
        vars.concat message_array[idx...message_array.length]
        break
      end
      if pattern[idx] == :one
        vars.push message_array[idx]
        length += 1
        next
      end
      found = pattern[idx] == message_array[idx]
      break unless found
      exact_length += 1
    end
    next unless found
    if best_length < exact_length
      best_length = exact_length
      best = act
      best_vars = vars
    elsif best_length < length
      best_length = length
      best = act
      best_vars = vars
    end
  end
  [ best, best_vars ]
end
clone() click to toggle source
# File lib/datalackeylib.rb, line 206
def clone
  gens = @generators
  @generators = nil
  copy = Marshal.load(Marshal.dump(self))
  @generators = gens
  copy.generators = gens.clone
  copy
end
fill_pattern2action_maps(actionlist, item) click to toggle source
# File lib/datalackeylib.rb, line 170
def fill_pattern2action_maps(actionlist, item)
  if item.is_a? Array
    unless item.first.is_a?(Array) || item.first.is_a?(Hash)
      # item is a pattern.
      raise ArgumentError, "Pattern-array must be under action: #{item}" if actionlist.empty?
      wildcards = false
      pattern = [ :identifier ]
      item.each do |element|
        case element
        when '?'
          wildcards = true
          pattern.push :one
        when '*'
          wildcards = true
          pattern.push :rest
          break
        else pattern.push element
        end
      end
      tgt = wildcards ? @pattern2act : @fixed2act
      tgt[pattern] = [] unless tgt.key? pattern
      tgt[pattern].push actionlist
      return
    end
    item.each { |sub| fill_pattern2action_maps(actionlist, sub) }
  elsif item.is_a? Hash
    item.each_pair do |action, sub|
      acts = actionlist.clone
      acts.push action
      fill_pattern2action_maps(acts, sub)
    end
  else
    raise ArgumentError, 'Item not a mapping, array, or pattern-array.'
  end
end
replace_identifier(identifier, p2a) click to toggle source
# File lib/datalackeylib.rb, line 215
def replace_identifier(identifier, p2a)
  altered = { }
  p2a.each_pair do |pattern, a|
    p = []
    pattern.each { |item| p.push(item == :identifier ? identifier : item) }
    altered[p] = a
  end
  altered
end
set_identifier(identifier) click to toggle source
# File lib/datalackeylib.rb, line 225
def set_identifier(identifier)
  @pattern2act = replace_identifier(identifier, @pattern2act)
  @fixed2act = replace_identifier(identifier, @fixed2act)
  @identifier = identifier
end