class SexpPath::SexpQueryBuilder
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
.
Public Class Methods
Matches only when all sub expressions match
example:
s(:a) / Q?{ all(s(:a), s(:b)) } #=> [] s(:a,:b) / Q?{ t(:a), include(:b)) } #=> [s(:a,:b)]
# File lib/sexp_path/sexp_query_builder.rb, line 115 def all(*args) SexpPath::Matcher::All.new(*args) end
Matches when any of the sub expressions match.
example:
s(:a) / Q?{ any(s(:a), s(:b)) } #=> [s(:a)] s(:a) / Q?{ any(s(:b), s(:c)) } #=> []
# File lib/sexp_path/sexp_query_builder.rb, line 105 def any(*args) SexpPath::Matcher::Any.new(*args) end
Matches any atom.
example:
s(:a) / Q?{ s(atom) } #=> [s(:a)] s(:a, s(:b)) / Q?{ s(atom) } #=> [s(:b)]
# File lib/sexp_path/sexp_query_builder.rb, line 95 def atom SexpPath::Matcher::Atom.new end
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)))))]
# File lib/sexp_path/sexp_query_builder.rb, line 134 def child(child) SexpPath::Matcher::Child.new(child) end
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() }
# File lib/sexp_path/sexp_query_builder.rb, line 32 def do(&block) instance_eval(&block) end
Matches an expression or any expression that includes the child.
example:
s(:a, :b) / Q?{ include(:b) } s(s(s(:a))) / Q?{ include(:a) }
# File lib/sexp_path/sexp_query_builder.rb, line 85 def include(child) SexpPath::Matcher::Include.new(child) end
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) } #=> []
# File lib/sexp_path/sexp_query_builder.rb, line 125 def is_not(arg) SexpPath::Matcher::Not.new(arg) end
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)]
# File lib/sexp_path/sexp_query_builder.rb, line 154 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
Matches all remaining input. This is a special case pattern and has a few odd characteristics.
-
You cannot capture with
remaining
-
If remaining comes before any other matchers, they will be ignored.
example:
s(:a) / Q?{ s(:a, ___ ) } #=> [s(:a)] s(:a, :b, :c) / Q?{ s(:a, ___ ) } #=> [s(:a, :b, :c)]
Can also be called with remaining
s(:a) / Q?{ s(:a, remaining) } #=> [s(:a)]
# File lib/sexp_path/sexp_query_builder.rb, line 74 def remaining() SexpPath::Matcher::Remaining.new end
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)]
# File lib/sexp_path/sexp_query_builder.rb, line 43 def s(*args) SexpPath::Matcher::Base.new(*args) end
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)]
# File lib/sexp_path/sexp_query_builder.rb, line 144 def t(name) SexpPath::Matcher::Type.new(name) end
Matches any single item.
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)]
# File lib/sexp_path/sexp_query_builder.rb, line 56 def wild() SexpPath::Matcher::Wild.new end