Module: PatternMatching::Collector

Defined in:
lib/patternmatching/pattern.rb

Overview

Private module for pattern matching and to collect var/val pairs

Class Method Summary collapse

Class Method Details

.walk(source, target, list) ⇒ Object



129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/patternmatching/pattern.rb', line 129

def self.walk(source, target, list)
  case source
  when Symbol
    list[source] = target
  when Node
    walk_node(source, target, list)
  when Hash
    walk_hash(source, target, list)
  when Enumerable
    walk_enumerable(source, target, list)
  else
    raise NotMatched.new unless source === target
  end
end

.walk_enumerable(source, target, list) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/patternmatching/pattern.rb', line 161

def self.walk_enumerable(source, target, list)
  if source.size == 0 and not (target == nil or target.size == 0)
    raise NotMatched.new 
  end
  source.size.times do |i|
    svalue = source[i]
    if i + 1 == source.size 
      if  svalue.class == Node and svalue.name == :_! and 
          svalue.size == 1
        tvalue = target[i .. -1]
        tvalue = if tvalue == nil then [] else tvalue end
        walk(svalue[0], tvalue, list)
      else
        raise NotMatched.new if source.size != target.size
        walk(svalue, target[i], list)
      end
    else
      raise NotMatched.new if target.size <= i
      walk(svalue, target[i], list)
    end
  end
end

.walk_hash(source, target, list) ⇒ Object



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/patternmatching/pattern.rb', line 184

def self.walk_hash(source, target, list)
  begin
    case target
    when Node
      raise NotMatched.new
    when Hash
      source.each do |key, svalue|
        walk(svalue, target[key], list)
      end
    else
      source.each do |key, svalue|
        walk(svalue, target.send(key), list)
      end
    end
  rescue
    raise NotMatched.new
  end
end

.walk_node(source, target, list) ⇒ Object



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/patternmatching/pattern.rb', line 144

def self.walk_node(source, target, list)
  return if source.name == :_ and source.size == 0
  begin
    if source.size != target.size
      raise NotMatched.new 
    end
    if source.name != :_ and source.name != target.name
      raise NotMatched.new
    end
  rescue
    raise NotMatched.new
  end
  source.size.times do |i|
    walk(source[i], target[i], list)
  end
end