class Patm::Rule

Public Class Methods

new(&block) click to toggle source
# File lib/patm.rb, line 545
def initialize(&block)
  # [[Pattern, Proc]...]
  @rules = []
  @else = nil
  block[self]
end

Public Instance Methods

apply(obj, _self = nil) click to toggle source
# File lib/patm.rb, line 560
def apply(obj, _self = nil)
  match = Match.new
  @rules.each do|(pat, block)|
    if pat.execute(match, obj)
      return block.call(match, _self)
    end
  end
  @else ? @else[obj, _self] : (raise NoMatchError.new(obj))
end
compile() click to toggle source
# File lib/patm.rb, line 578
def compile
  i = 0
  ctxs = []
  srcs = []
  @rules.each do|pat, block|
    s, c, i = pat.compile_internal(i, '_obj')
    ctxs << c
    ctxs << [block]
    srcs << "if (#{s || 'true'})\n_ctx[#{i}].#{compile_call(block, "::Patm::Match.new(_match)"," _self")}"
    i += 1
  end
  src = srcs.join("\nels")
  if @else
    src << "\nelse\n" unless srcs.empty?
    src << "_ctx[#{i}].#{compile_call(@else, "_obj"," _self")}"
    ctxs << [@else]
    i += 1
  else
    src << "\nelse\n" unless srcs.empty?
    src << "raise ::Patm::NoMatchError.new(_obj)"
  end
  src << "\nend" unless srcs.empty?
  Compiled.new(
    src,
    ctxs.flatten(1)
  )
end
compile_call(block, *args) click to toggle source
# File lib/patm.rb, line 574
def compile_call(block, *args)
  "call(#{args[0...block.arity].join(', ')})"
end
else(&block) click to toggle source
# File lib/patm.rb, line 556
def else(&block)
  @else = block
end
inspect() click to toggle source
# File lib/patm.rb, line 570
def inspect
  "Rule{#{@rules.map(&:first).map(&:inspect).join(', ')}#{@else ? ', _' : ''}}"
end
on(pat, &block) click to toggle source
# File lib/patm.rb, line 552
def on(pat, &block)
  @rules << [Pattern.build_from(pat), block]
end