Class: SexpPath::SexpQueryBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/sexp_path/sexp_query_builder.rb

Overview

The SexpQueryBuilder is the simplest way to build SexpPath queries.

Typically, one access the SexpQueryBuilder through the helper method Q? which accepts a block, and will return a SexpPath matcher.

For example here is a SexpPath query that looks for s(:a):

query = Q?{ s(:a) }

A more interesting query might look for classes with names starting in Test:

query = Q?{ s(:class, m(/^Test\w+/ % 'name', _, _)) }

This makes use of a SexpPath::Matcher::Pattern, two SexpPath::Matcher::Wild matchers and SexpPath::Traverse#capture_as for capturing the name to a variable ‘name’.

For more examples, see the various SexpQueryBuilder class methods, the examples, and the tests supplied with SexpPath.

Class Method Summary collapse

Class Method Details

.all(*args) ⇒ Object

Matches when all sub expression match

example:

s(:a) / Q?{ all(s(:a), s(:b)) } #=> []
s(:a,:b) / Q?{ t(:a), include(:b)) } #=> [s(:a,:b)]


91
92
93
# File 'lib/sexp_path/sexp_query_builder.rb', line 91

def all(*args)
  SexpPath::Matcher::All.new(*args)
end

.any(*args) ⇒ Object

Matches when any sub expression match

example:

s(:a) / Q?{ any(s(:a), s(:b)) } #=> [s(:a)]
s(:a) / Q?{ any(s(:b), s(:c)) } #=> []


81
82
83
# File 'lib/sexp_path/sexp_query_builder.rb', line 81

def any(*args)
  SexpPath::Matcher::Any.new(*args)
end

.atomObject

Matches any atom.

example:

s(:a) / Q?{ s(atom) }        #=> [s(:a)]
s(:a, s(:b)) / Q?{ s(atom) } #=> [s(:b)]


71
72
73
# File 'lib/sexp_path/sexp_query_builder.rb', line 71

def atom
  SexpPath::Matcher::Atom.new
end

.child(child) ⇒ Object

Matches anything that has a child matching the sub expression

example:

s(s(s(s(s(:a))))) / Q?{ child(s(:a)) } #=> [s(s(s(s(s(:a)))))]


110
111
112
# File 'lib/sexp_path/sexp_query_builder.rb', line 110

def child(child)
  SexpPath::Matcher::Child.new(child)
end

.do(&block) ⇒ Object

This is the longhand method for create a SexpPath query, normally one would use Q?{ … }, however it is also possible to do:

SexpPath::SexpQueryBuilder.do{ s() }


32
33
34
# File 'lib/sexp_path/sexp_query_builder.rb', line 32

def do(&block)
  instance_eval(&block)
end

.include(child) ⇒ Object



61
62
63
# File 'lib/sexp_path/sexp_query_builder.rb', line 61

def include(child)
  SexpPath::Matcher::Include.new(child)
end

.is_not(arg) ⇒ Object

Matches when sub expression does not match, see SexpPath::Matcher::Base#-@

example:

s(:a) / Q?{ is_not(s(:b)) } #=> [s(:a)]
s(:a) / Q?{ s(is_not :a) } #=> []


101
102
103
# File 'lib/sexp_path/sexp_query_builder.rb', line 101

def is_not(arg)
  SexpPath::Matcher::Not.new(arg)
end

.m(*patterns) ⇒ Object

Matches any atom who’s string representation matches the patterns passed in.

example:

s(:a) / Q?{ m('a') } #=> [s(:a)]
s(:a) / Q?{ m(/\w/,/\d/) } #=> [s(:a)]
s(:tests, s(s(:test_a), s(:test_b))) / Q?{ m(/test_\w/) } #=> [s(:test_a), s(:test_b)]


130
131
132
133
134
# File 'lib/sexp_path/sexp_query_builder.rb', line 130

def m(* patterns)
  patterns = patterns.map{|p| p.is_a?(Regexp) ? p : Regexp.new("\\A"+Regexp.escape(p.to_s)+"\\Z")}
  regexp = Regexp.union(*patterns)
  SexpPath::Matcher::Pattern.new(regexp)
end

.s(*args) ⇒ Object

Matches an S-Expression.

example

s(:a) / Q?{ s(:a) }       #=> [s(:a)]
s(:a) / Q?{ s() }         #=> []
s(:a, s(:b) / Q?{ s(:b) } #=> [s(:b)]


43
44
45
# File 'lib/sexp_path/sexp_query_builder.rb', line 43

def s(*args)
  SexpPath::Matcher::Base.new(*args)
end

.t(name) ⇒ Object

Matches anything having the same sexp_type, which is the first value in a Sexp.

example:

s(:a, :b) / Q?{ t(:a) } #=> [s(:a, :b)]
s(:a, :b) / Q?{ t(:b) } #=> []
s(:a, s(:b, :c)) / Q?{ t(:b) } #=> [s(:b, :c)]


120
121
122
# File 'lib/sexp_path/sexp_query_builder.rb', line 120

def t(name)
  SexpPath::Matcher::Type.new(name)
end

.wildObject Also known as: _

Matches anything.

example:

s(:a) / Q?{ _ }        #=> [s(:a)]
s(:a, s(s(:b))) / Q?{ s(_) } #=> [s(s(:b))]

Can also be called with wild

s(:a) / Q?{ wild }     #=> [s(:a)]


56
57
58
# File 'lib/sexp_path/sexp_query_builder.rb', line 56

def wild()
  SexpPath::Matcher::Wild.new
end