Class: Sexp::Sibling

Inherits:
Matcher show all
Defined in:
lib/sexp_matcher.rb

Overview

See Matcher for sibling relations: <,<<,>>,>

Constant Summary

Constants inherited from Sexp

UNASSIGNED

Instance Attribute Summary collapse

Attributes inherited from Sexp

#comments, #file, #line, #line_max

Instance Method Summary collapse

Methods inherited from Matcher

#&, #-@, #/, #=~, #>>, #greedy?, match_subs=, match_subs?, parse, #|

Methods inherited from Sexp

#/, #=~, _, ___, all, any, #array_type?, atom, child, #compact, #deep_each, #depth, #each_of_type, #each_sexp, #eql?, #find_and_replace_all, #find_node, #find_nodes, from_array, #gsub, #hash, include, k, m, #map, #mass, #method_missing, #new, not?, q, #replace_sexp, #respond_to?, s, #search_each, #sexp_body, #sexp_body=, #sexp_type, #sexp_type=, #shift, #structure, #sub, t, #to_a, #value

Constructor Details

#initialize(subject, sibling, distance = nil) ⇒ Sibling

Creates a Matcher which will match any pair of Sexps that are siblings. Defaults to matching the immediate following sibling.



1002
1003
1004
1005
1006
# File 'lib/sexp_matcher.rb', line 1002

def initialize subject, sibling, distance = nil
  @subject = subject
  @sibling = sibling
  @distance = distance
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Sexp

Instance Attribute Details

#distanceObject (readonly)

An optional distance requirement for the matcher.



996
997
998
# File 'lib/sexp_matcher.rb', line 996

def distance
  @distance
end

#siblingObject (readonly)

The RHS of the matcher.



991
992
993
# File 'lib/sexp_matcher.rb', line 991

def sibling
  @sibling
end

#subjectObject (readonly)

The LHS of the matcher.



986
987
988
# File 'lib/sexp_matcher.rb', line 986

def subject
  @subject
end

Instance Method Details

#==(o) ⇒ Object

:nodoc:



1027
1028
1029
1030
1031
1032
# File 'lib/sexp_matcher.rb', line 1027

def == o # :nodoc:
  super &&
    self.subject  == o.subject &&
    self.sibling  == o.sibling &&
    self.distance == o.distance
end

#inspectObject

:nodoc:



1034
1035
1036
# File 'lib/sexp_matcher.rb', line 1034

def inspect # :nodoc:
  "%p >> %p" % [subject, sibling]
end

#pretty_print(q) ⇒ Object

:nodoc:



1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
# File 'lib/sexp_matcher.rb', line 1038

def pretty_print q # :nodoc:
  if distance then
    q.group 1, "sibling(", ")" do
      q.seplist [subject, sibling, distance] do |v|
        q.pp v
      end
    end
  else
    q.group 1 do
      q.pp subject
      q.text " >> "
      q.pp sibling
    end
  end
end

#satisfy?(o) ⇒ Boolean

Satisfied if o contains subject followed by sibling

Returns:

  • (Boolean)


1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
# File 'lib/sexp_matcher.rb', line 1011

def satisfy? o
  # Future optimizations:
  # * Shortcut matching sibling
  subject_matches = index_matches(subject, o)
  return nil if subject_matches.empty?

  sibling_matches = index_matches(sibling, o)
  return nil if sibling_matches.empty?

  subject_matches.any? { |i1, _data_1|
    sibling_matches.any? { |i2, _data_2|
      distance ? (i2-i1 == distance) : i2 > i1
    }
  }
end