Class: DJC::DSL
- Inherits:
-
Object
- Object
- DJC::DSL
- Defined in:
- lib/djc.rb
Instance Method Summary collapse
- #* ⇒ Object
- #+@ ⇒ Object
- #>(other) ⇒ Object (also: #%)
- #__djc_build_name(rule = nil) ⇒ Object
- #__djc_dsl(name, *args, &block) ⇒ Object
- #__djc_partial(name) ⇒ Object
- #__djc_reparent(parent) ⇒ Object
- #avg(*args, &block) ⇒ Object
- #capture(regex = nil, *captures, &block) ⇒ Object
- #compose(*args, &block) ⇒ Object
- #count(compact = false, &block) ⇒ Object
- #emit_name(name = nil) ⇒ Object
- #find(rule, &block) ⇒ Object (also: #match, #with, #field)
-
#initialize(rule = nil, parent = nil, name = parent.attempt(rule).__djc_build_name(rule), &block) ⇒ DSL
constructor
A new instance of DSL.
- #join(delimiter = $,, &block) ⇒ Object
- #method_missing(name, *args, &block) ⇒ Object
- #parse(data, extract = true) ⇒ Object
- #rule_parse(data) ⇒ Object
- #sort(*args, &block) ⇒ Object
- #sum(initial = 0.0, op = :+, &block) ⇒ Object
- #to_s(depth = 0) ⇒ Object
- #to_str ⇒ Object
- #uniq(*args, &block) ⇒ Object
- #~@ ⇒ Object
Constructor Details
#initialize(rule = nil, parent = nil, name = parent.attempt(rule).__djc_build_name(rule), &block) ⇒ DSL
Returns a new instance of DSL.
178 179 180 181 182 183 184 185 |
# File 'lib/djc.rb', line 178 def initialize(rule = nil, parent = nil, name = parent.attempt(rule).__djc_build_name(rule), &block) @rule, @parent, @name, @capture, @finder, @nodes, @composer, @splatter, @partials = rule, parent, name, false, false, [], [], false, {} ctx(:djc_dsl_def) do ctx[:dsl] = self instance_eval(&block) end if block self end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object
334 335 336 |
# File 'lib/djc.rb', line 334 def method_missing(name, *args, &block) __djc_dsl(name, *args, &block) end |
Instance Method Details
#* ⇒ Object
286 287 288 289 |
# File 'lib/djc.rb', line 286 def *(*) @splatter = true self end |
#+@ ⇒ Object
190 191 192 193 194 |
# File 'lib/djc.rb', line 190 def +@() @capture = true @rule = @rule.gsub(/^\/([^()]*)\/$/, '/(\1)/') if @finder self end |
#>(other) ⇒ Object Also known as: %
195 196 197 198 |
# File 'lib/djc.rb', line 195 def >(other) @name = other self end |
#__djc_build_name(rule = nil) ⇒ Object
175 |
# File 'lib/djc.rb', line 175 def __djc_build_name(rule = nil) @name ? "#{@name}_#{rule}" : rule end |
#__djc_dsl(name, *args, &block) ⇒ Object
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 |
# File 'lib/djc.rb', line 315 def __djc_dsl(name, *args, &block) if name.to_s[0] == '_' if block @partials[name] = block self else partial = __djc_partial(name) dsl = instance_exec(*args, &partial) dsl.__djc_reparent(self) @nodes << dsl dsl end else dsl = DSL.new(name, self, *args, &block) @nodes << dsl dsl end end |
#__djc_partial(name) ⇒ Object
311 312 313 |
# File 'lib/djc.rb', line 311 def __djc_partial(name) @partials[name] || @parent.__djc_partial(name) end |
#__djc_reparent(parent) ⇒ Object
176 |
# File 'lib/djc.rb', line 176 def __djc_reparent(parent) @parent = parent end |
#avg(*args, &block) ⇒ Object
249 250 251 252 253 254 255 256 |
# File 'lib/djc.rb', line 249 def avg(*args, &block) if ctx[:dsl] == self __djc_dsl(:avg, *args, &block) else compose { |*values| (values.map(&:to_f).inject(0.0, :+) / values.size) if values } self end end |
#capture(regex = nil, *captures, &block) ⇒ Object
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 |
# File 'lib/djc.rb', line 291 def capture(regex = nil, *captures, &block) if ctx[:dsl] == self args = [regex, *captures].compact __djc_dsl(:capture, *args, &block) else compose do |value| if (match = regex.match(value.to_s)) if captures.empty? block ? block.call(match) : match.captures else symbols = captures.any? { |i| i.is_a?(String) || i.is_a?(Symbol) } captured = symbols ? captures.map { |name| match[name] } : match.to_a.values_at(*captures) block ? block.call(*captured) : captured end.sequester end end self end end |
#compose(*args, &block) ⇒ Object
220 221 222 223 224 225 226 227 |
# File 'lib/djc.rb', line 220 def compose(*args, &block) if ctx[:dsl] == self __djc_dsl(:compose, *args, &block) else @composer << block self end end |
#count(compact = false, &block) ⇒ Object
276 277 278 279 280 281 282 283 284 |
# File 'lib/djc.rb', line 276 def count(compact = false, &block) if ctx[:dsl] == self args = compact ? [compact] : [] __djc_dsl(:count, *args, &block) else compose { |*values| compact ? values.compact.size : values.size } self end end |
#emit_name(name = nil) ⇒ Object
166 167 168 169 170 171 172 173 174 |
# File 'lib/djc.rb', line 166 def emit_name(name = nil) if @name.is_a?(Proc) @name.call(name) elsif @finder && name name else "#@name#{ "_#{name}" if name }" end end |
#find(rule, &block) ⇒ Object Also known as: match, with, field
212 213 214 215 |
# File 'lib/djc.rb', line 212 def find(rule, &block) rule = rule.inspect if rule.is_a?(Regexp) ~__djc_dsl(rule, &block) end |
#join(delimiter = $,, &block) ⇒ Object
229 230 231 232 233 234 235 236 237 |
# File 'lib/djc.rb', line 229 def join(delimiter=$,, &block) if ctx[:dsl] == self args = delimiter != $, ? [delimiter] : [] __djc_dsl(:join, *args, &block) else compose { |*values| [*values].join(delimiter) } self end end |
#parse(data, extract = true) ⇒ Object
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 |
# File 'lib/djc.rb', line 358 def parse(data, extract = true) if @capture rule_parse(data) else data = if @finder && extract @rule.to_s.walk(data) elsif data && @rule && extract && data.is_a?(Hash) data[@rule] else data end if data.is_a?(Array) data.flat_map do |element| parse(element, false) end else @nodes.inject([]) do |rows, node| result = node.parse(data) result.flat_map do |res| rows.empty? ? res : rows.map { |row| row.merge(res) } end end end end end |
#rule_parse(data) ⇒ Object
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 |
# File 'lib/djc.rb', line 338 def rule_parse(data) if data.is_a?(Array) data.flat_map do |element| rule_parse(element) end else values = @rule.to_s.walk(data) row = if (@splatter || @finder) && values.is_a?(Hash) values.each.with_object({}) { |(k, v), r| r[emit_name(k)] = v } elsif @splatter && values.is_a?(Array) values.each.with_index.with_object({}) { |(v, i), r| r[emit_name(i)] = v } else { emit_name => values } end [ @composer.empty? ? row : row.each.with_object({}) { |(k,v), r| r[k] = @composer.inject(v) { |m,c| c.call(*m) } } ] end end |
#sort(*args, &block) ⇒ Object
258 259 260 261 262 263 264 265 |
# File 'lib/djc.rb', line 258 def sort(*args, &block) if ctx[:dsl] == self __djc_dsl(:sort, *args, &block) else compose { |*sort| sort.compact.sort(&block) } self end end |
#sum(initial = 0.0, op = :+, &block) ⇒ Object
239 240 241 242 243 244 245 246 247 |
# File 'lib/djc.rb', line 239 def sum(initial = 0.0, op = :+, &block) if ctx[:dsl] == self args = initial != 0.0 ? [initial] : [] __djc_dsl(:sum, *args, &block) else compose { |*values| values.map(&:to_f).inject(initial, block ? block : op) if values } self end end |
#to_s(depth = 0) ⇒ Object
202 203 204 205 206 207 208 209 210 |
# File 'lib/djc.rb', line 202 def to_s(depth = 0) str = "DJC:" str += @capture ? "+" : "" str += (@rule || "ROOT").to_s str += "(#@name)" if @name str += " [#{@partials.keys.join(",")}]" unless @partials.empty? str += " {\n#{@nodes.map {|n| (" " * (depth + 1)) + n.to_s(depth + 1)}.join("\n") }\n#{" " * depth}}" unless @nodes.empty? str end |
#to_str ⇒ Object
201 |
# File 'lib/djc.rb', line 201 def to_str() to_s end |
#uniq(*args, &block) ⇒ Object
267 268 269 270 271 272 273 274 |
# File 'lib/djc.rb', line 267 def uniq(*args, &block) if ctx[:dsl] == self __djc_dsl(:uniq, *args, &block) else compose { |*values| values.uniq } self end end |
#~@ ⇒ Object
186 187 188 189 |
# File 'lib/djc.rb', line 186 def ~@() @finder = true self end |